From df38aad2b56c0f80059e2ae3417182b57926783d Mon Sep 17 00:00:00 2001
From: 疯狂的狮子li <15040126243@163.com>
Date: 星期五, 31 三月 2023 18:39:10 +0800
Subject: [PATCH] update 更改包名为 org.dromara update 更改文档地址为 plus-doc.dromara.org

---
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysMenuController.java                                      |  182 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDataScopeService.java                                             |   26 
 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlusDataPermissionInterceptor.java                 |  107 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysRole.java                                                           |   79 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginBody.java                                          |   48 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysPostVo.java                                                      |   73 
 ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/properties/TenantProperties.java                                 |   27 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOperLogServiceImpl.java                                       |  144 
 ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/annotation/Log.java                                                    |   48 
 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysTenantMapper.xml                                                           |    2 
 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/I18nConfig.java                                                 |   22 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysOperlogController.java                                  |   75 
 ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/exception/TenantException.java                                   |   20 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPermissionServiceImpl.java                                    |   61 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ServletUtils.java                                              |  193 
 ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/properties/MailProperties.java                                |   69 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysRoleMenu.java                                                       |   29 
 ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/BusinessType.java                                                |   58 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/package-info.java                                                      |    1 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/mapper/TestTreeMapper.java                                                        |   21 
 ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/core/SmsTemplate.java                                                  |   26 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/ProfileVo.java                                                      |   29 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysOssController.java                                       |  108 
 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/interceptor/PlusWebInvokeTimeInterceptor.java                          |   94 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/DemoModeException.java                                     |   17 
 ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/config/JacksonConfig.java                                            |   47 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/MetaVo.java                                                         |   61 
 ruoyi-common/ruoyi-common-mail/pom.xml                                                                                                    |    4 
 ruoyi-common/ruoyi-common-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports       |    2 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/TestDemo.java                                                              |   68 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/queue/PriorityQueueController.java                                     |   89 
 ruoyi-extend/ruoyi-xxl-job-admin/pom.xml                                                                                                  |    2 
 ruoyi-common/ruoyi-common-oss/pom.xml                                                                                                     |    6 
 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/enums/CaptchaType.java                                                 |   29 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysOssConfigMapper.java                                                |   16 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysCache.java                                                          |   47 
 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml                                                         |    2 
 pom.xml                                                                                                                                   |   12 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysRoleBo.java                                                      |   97 
 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/UndertowConfig.java                                             |   30 
 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/config/TranslationConfig.java                          |   50 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/DeptTreeSelectVo.java                                               |   26 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserImportVo.java                                                |   76 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java                                                      |  137 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysTenantVo.java                                                    |  115 
 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/config/EncryptorAutoConfiguration.java                         |   41 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysMenuMapper.java                                                     |   83 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysMenuService.java                                                  |  147 
 ruoyi-common/ruoyi-common-encrypt/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports     |    2 
 ruoyi-common/ruoyi-common-translation/pom.xml                                                                                             |    4 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserInfoVo.java                                                  |   40 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/QueryGroup.java                                             |    9 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisCacheController.java                                              |   95 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysTenantPackageMapper.java                                            |   14 
 ruoyi-admin/src/main/java/org/dromara/web/controller/IndexController.java                                                                 |   32 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDeptService.java                                                  |  118 
 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/Sm2Encryptor.java                               |   64 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/GlobalConstants.java                                        |   39 
 ruoyi-common/ruoyi-common-mybatis/pom.xml                                                                                                 |    6 
 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/page/PageQuery.java                                       |  114 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/DictService.java                                             |   57 
 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/enumd/AlgorithmType.java                                       |   48 
 ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/entity/SmsResult.java                                                  |   31 
 ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/properties/XxlJobProperties.java                                |   40 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysMenuBo.java                                                      |  111 
 ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java                                                               |  135 
 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelDictConvert.java                                      |   73 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssConfigServiceImpl.java                                     |  183 
 ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/aspect/LogAspect.java                                                  |  221 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysLogininfor.java                                                     |   75 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysDictDataVo.java                                                  |   95 
 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/OssUrlTranslationImpl.java                   |   28 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysConfigController.java                                    |  137 
 ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/handler/OpenApiHandler.java                                            |  252 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/RuoYiConfig.java                                              |   49 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysNoticeMapper.java                                                   |   14 
 ruoyi-modules/ruoyi-system/pom.xml                                                                                                        |   28 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ValidatorConfig.java                                          |   39 
 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml                                                         |    2 
 ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/exception/OssException.java                                            |   19 
 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/enums/CaptchaCategory.java                                             |   35 
 ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/config/RateLimiterConfig.java                          |   20 
 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysLogininforMapper.xml                                                       |    2 
 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysTenantPackageMapper.xml                                                    |    2 
 ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java                                         |  110 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/impl/TestTreeServiceImpl.java                                             |   87 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/MessageUtils.java                                              |   28 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUserPost.java                                                       |   29 
 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/enums/DataBaseType.java                                        |   49 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMenu.java                                                           |  191 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/LoginType.java                                                 |   44 
 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java                               |   64 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantPackageServiceImpl.java                                 |  139 
 ruoyi-common/ruoyi-common-bom/pom.xml                                                                                                     |   44 
 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java                                               |  327 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java                                    |  174 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysDictTypeMapper.java                                                 |   14 
 ruoyi-common/ruoyi-common-idempotent/src/main/java/org/dromara/common/idempotent/annotation/RepeatSubmit.java                             |   29 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisLockController.java                                               |   71 
 ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/LogininforEvent.java                                             |   52 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/ITestTreeService.java                                                     |   52 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java                                             |   18 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Threads.java                                                   |   75 
 ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/UserPassAuthenticator.java                                     |   33 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/StringUtils.java                                               |  321 
 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/IEncryptor.java                                           |   35 
 ruoyi-common/ruoyi-common-mybatis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports     |    2 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysDictData.java                                                       |   76 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisRateLimiterController.java                                        |   52 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysTenantPackageService.java                                         |   52 
 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/Sm4Encryptor.java                               |   67 
 ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/PlusSpringCacheManager.java                                |  191 
 ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsConfig.java                                                  |   48 
 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/filter/RepeatedlyRequestWrapper.java                                   |   68 
 ruoyi-common/ruoyi-common-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports         |   10 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysDictDataMapper.java                                                 |   25 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysOssUploadVo.java                                                 |   28 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysOssMapper.java                                                      |   13 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysNoticeController.java                                    |   81 
 ruoyi-common/ruoyi-common-websocket/pom.xml                                                                                               |   10 
 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataBaseHelper.java                                     |   72 
 ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/handler/GlobalExceptionHandler.java                          |  141 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/ConfigService.java                                           |   18 
 ruoyi-common/ruoyi-common-ratelimiter/pom.xml                                                                                             |    6 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictDataServiceImpl.java                                      |  139 
 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/enumd/EncodeType.java                                          |   26 
 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/properties/EncryptorProperties.java                            |   48 
 ruoyi-modules/ruoyi-job/src/main/java/org/dromara/job/service/SampleService.java                                                          |  252 
 ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/constant/OssConstant.java                                              |   38 
 ruoyi-modules/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml                                                      |   30 
 ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/core/AliyunSmsTemplate.java                                            |   66 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/RoleDTO.java                                              |   38 
 ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/handle/TenantKeyPrefixHandler.java                               |   58 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysConfigService.java                                                |   87 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysLogininforVo.java                                                |   93 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysLogininforBo.java                                                |   77 
 ruoyi-common/ruoyi-common-web/pom.xml                                                                                                     |    6 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysDeptVo.java                                                      |   91 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/ITestDemoService.java                                                     |   71 
 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisEncryptInterceptor.java                     |  116 
 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/annotation/Translation.java                            |   39 
 ruoyi-modules/ruoyi-generator/pom.xml                                                                                                     |   12 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/DateUtils.java                                                 |  168 
 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml                                                             |    4 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/ServiceException.java                                      |   67 
 ruoyi-common/ruoyi-common-idempotent/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports  |    2 
 ruoyi-admin/src/test/java/org/dromara/test/ParamUnitTest.java                                                                             |   72 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysDept.java                                                           |   78 
 ruoyi-common/ruoyi-common-json/pom.xml                                                                                                    |    4 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java                                                     |  145 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDeptBo.java                                                      |   73 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/AsyncConfig.java                                              |   54 
 ruoyi-common/ruoyi-common-doc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports         |    2 
 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/handler/TranslationBeanSerializerModifier.java    |   29 
 ruoyi-common/ruoyi-common-json/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports        |    2 
 ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm                                                              |    9 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java                                          |  325 
 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/mapper/BaseMapperPlus.java                                |  198 
 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/properties/CaptchaProperties.java                               |   38 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysNoticeService.java                                                |   67 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/Constants.java                                              |   81 
 ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/config/SwaggerConfig.java                                              |  126 
 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/RsaEncryptor.java                               |   65 
 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java                                  |  102 
 ruoyi-common/ruoyi-common-sms/pom.xml                                                                                                     |    4 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysNoticeBo.java                                                    |   65 
 ruoyi-common/ruoyi-common-doc/pom.xml                                                                                                     |    4 
 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/config/WebSocketConfig.java                                |   60 
 ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/GenTableServiceImpl.java                                        |  459 
 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/annotation/CellMerge.java                                          |   24 
 ruoyi-admin/src/main/java/org/dromara/web/domain/vo/LoginVo.java                                                                          |   15 
 ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/utils/JsonUtils.java                                                 |  113 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/MenuTreeSelectVo.java                                               |   26 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java                                          |  525 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/CacheController.java                                       |   55 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/AddGroup.java                                               |    9 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/vo/TestTreeVo.java                                                         |   64 
 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/annotation/EncryptField.java                                   |   44 
 ruoyi-common/ruoyi-common-idempotent/src/main/java/org/dromara/common/idempotent/config/IdempotentConfig.java                             |   21 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/impl/TestDemoServiceImpl.java                                             |  110 
 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml                                                         |    2 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysTenantPackageBo.java                                             |   59 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/SpringUtils.java                                               |   62 
 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/annotation/ExcelDictFormat.java                                    |   32 
 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/CaptchaConfig.java                                              |   65 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/queue/DelayedQueueController.java                                      |   90 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java                                      |  261 
 ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/properties/RedissonProperties.java                          |  135 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/TestTree.java                                                              |   65 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysNoticeVo.java                                                    |   73 
 ruoyi-common/ruoyi-common-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports    |    6 
 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/core/BaseController.java                                               |   40 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysRoleController.java                                      |  250 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysLogininforService.java                                            |   47 
 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/EncryptContext.java                                       |   41 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysOssConfigVo.java                                                 |   97 
 ruoyi-common/ruoyi-common-websocket/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports   |    2 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/HttpStatus.java                                             |   93 
 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/ResourcesConfig.java                                            |   52 
 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/AesEncryptor.java                               |   69 
 ruoyi-modules/ruoyi-demo/pom.xml                                                                                                          |   34 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/package-info.java                                                          |    1 
 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml                                                         |    2 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/bo/TestDemoBo.java                                                         |   62 
 ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/mapper/GenTableColumnMapper.java                                        |   24 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysOssConfigService.java                                             |   65 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestSensitiveController.java                                           |   76 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysConfigMapper.java                                                   |   14 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssServiceImpl.java                                           |  171 
 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml                                                             |    4 
 ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java                                                                    |  391 
 ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/exception/SmsException.java                                            |   19 
 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/holder/WebSocketSessionHolder.java                         |   37 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysConfigVo.java                                                    |   72 
 ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/XxlJobConfig.java                                               |   38 
 README.md                                                                                                                                 |   35 
 ruoyi-common/ruoyi-common-satoken/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports     |    2 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/RegionUtils.java                                            |   67 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/EmailLoginBody.java                                     |   35 
 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/filter/XssHttpServletRequestWrapper.java                               |   97 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysConfigBo.java                                                    |   62 
 ruoyi-modules/ruoyi-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml                                                |   12 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/RegisterBody.java                                       |   17 
 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/annotation/ExcelEnumFormat.java                                    |   30 
 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml                                                             |    4 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/manager/ShutdownManager.java                                         |   41 
 ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java                                   |  176 
 ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/service/SaPermissionImpl.java                             |   47 
 ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/IGenTableService.java                                           |  133 
 ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/handle/PlusTenantLineHandler.java                                |   57 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysDictType.java                                                       |   46 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysPostController.java                                      |  115 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java                                                  |  205 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserPostMapper.java                                                 |   13 
 ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/handler/KeyPrefixHandler.java                                      |   50 
 ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/MonitorAdminApplication.java                                     |   19 
 ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/domain.java.vm                                                                   |    5 
 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/dto/WebSocketMessageDto.java                               |   29 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java                                          |  365 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysOssService.java                                                   |   33 
 ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/core/TenantEntity.java                                           |   21 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/MapstructUtils.java                                            |   92 
 ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/BusinessStatus.java                                              |   18 
 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/FilterConfig.java                                               |   53 
 ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailUtils.java                                                 |  469 
 ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/entity/UploadResult.java                                               |   24 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysDeptController.java                                      |  120 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysOperLogBo.java                                                   |  127 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysRoleDept.java                                                       |   29 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/mapper/TestDemoMapper.java                                                        |   58 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestExcelController.java                                               |   97 
 ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/annotation/Sensitive.java                                  |   24 
 ruoyi-admin/src/main/java/org/dromara/web/domain/vo/TenantListVo.java                                                                     |   22 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/TreeBuildUtils.java                                            |   35 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysConfigServiceImpl.java                                        |  216 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/UserStatus.java                                                |   30 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java                                                      |  134 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java                                          |  421 
 ruoyi-common/ruoyi-common-core/pom.xml                                                                                                    |    2 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/CaptchaExpireException.java                           |   18 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ApplicationConfig.java                                        |   16 
 ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/enumd/AccessPolicyType.java                                            |   55 
 ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java                                   |   59 
 ruoyi-modules/ruoyi-demo/src/main/resources/mapper/demo/TestTreeMapper.xml                                                                |    2 
 ruoyi-admin/src/test/java/org/dromara/test/AssertUnitTest.java                                                                            |   45 
 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/UserNameTranslationImpl.java                 |   26 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysOperLog.java                                                        |  115 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictTypeServiceImpl.java                                      |  268 
 ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/domain/GenTableColumn.java                                              |  223 
 ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/service.java.vm                                                                  |    4 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java                                             |   63 
 ruoyi-modules/ruoyi-demo/src/main/resources/mapper/demo/TestDemoMapper.xml                                                                |    4 
 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/DeptNameTranslationImpl.java                 |   28 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysPostBo.java                                                      |   62 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysNoticeServiceImpl.java                                        |  122 
 ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/enums/LimitType.java                                   |   24 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/xss/XssValidator.java                                                |   21 
 ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/config/TenantConfig.java                                         |  100 
 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/enums/DataScopeType.java                                       |   73 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysConfig.java                                                         |   51 
 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/utils/UnsignedMathGenerator.java                                       |   88 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysTenantMapper.java                                                   |   14 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/XcxLoginUser.java                                       |   27 
 ruoyi-admin/src/main/java/org/dromara/web/domain/vo/LoginTenantVo.java                                                                    |   25 
 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/domain/BaseEntity.java                                    |   71 
 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/handler/PlusWebSocketHandler.java                          |  103 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysTenantPackage.java                                                  |   54 
 ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/OperLogEvent.java                                                |  115 
 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/annotation/TranslationType.java                        |   23 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserPasswordNotMatchException.java                    |   18 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysRoleDeptMapper.java                                                 |   13 
 ruoyi-common/ruoyi-common-redis/pom.xml                                                                                                   |    4 
 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelBigNumberConvert.java                                 |   52 
 ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/config/AdminServerConfig.java                                    |   31 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysNotice.java                                                         |   51 
 ruoyi-admin/src/main/java/org/dromara/DromaraServletInitializer.java                                                                      |   18 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysOssConfig.java                                                      |   89 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/xss/Xss.java                                                         |   26 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDictDataBo.java                                                  |   88 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestDemoController.java                                                |  147 
 ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/handler/SensitiveHandler.java                              |   54 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysOperLogService.java                                               |   54 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysRoleService.java                                                  |  181 
 ruoyi-modules/pom.xml                                                                                                                     |    2 
 ruoyi-common/ruoyi-common-tenant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports      |    2 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/UserOnlineDTO.java                                        |   62 
 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml                                                             |    8 
 ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/properties/SecurityProperties.java                    |   21 
 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/AbstractEncryptor.java                          |   18 
 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictDataMapper.xml                                                         |    2 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysDictTypeVo.java                                                  |   66 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/EditGroup.java                                              |    9 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginUser.java                                          |  123 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantServiceImpl.java                                        |  375 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUserOnline.java                                                     |   54 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestTreeController.java                                                |  107 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysDictTypeController.java                                  |  125 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUser.java                                                           |  115 
 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/constant/WebSocketConstants.java                           |   28 
 ruoyi-admin/src/main/java/org/dromara/web/service/SysRegisterService.java                                                                 |  106 
 ruoyi-common/ruoyi-common-mail/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports        |    2 
 ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/config/SecurityConfig.java                                       |   52 
 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/properties/XssProperties.java                                   |   30 
 ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfig.java                                            |  130 
 ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/util/VelocityUtils.java                                                 |  335 
 ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/enumd/PolicyType.java                                                  |   35 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ValidatorUtils.java                                            |   28 
 ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/util/GenUtils.java                                                      |  233 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/CaptchaException.java                                 |   18 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/vo/TestDemoVo.java                                                         |  104 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/Swagger3DemoController.java                                            |   31 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysOssVo.java                                                       |   72 
 ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/listener/UserActionListener.java                               |  139 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysOperLogVo.java                                                   |  144 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserPasswordRetryLimitExceedException.java            |   19 
 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/ExcelListener.java                                            |   14 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/UserType.java                                                  |   37 
 ruoyi-common/ruoyi-common-sensitive/pom.xml                                                                                               |    4 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysLogininforMapper.java                                               |   14 
 ruoyi-common/ruoyi-common-excel/pom.xml                                                                                                   |    4 
 ruoyi-common/ruoyi-common-satoken/pom.xml                                                                                                 |    6 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/UtilException.java                                         |   26 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysMenuVo.java                                                      |  116 
 ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java                                                                  |  153 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/R.java                                                        |  110 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDataScopeServiceImpl.java                                     |   61 
 ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/RedisUtils.java                                              |  462 
 ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports |   10 
 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/config/MybatisPlusConfig.java                                  |  102 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/UserInfoVo.java                                                     |   30 
 ruoyi-admin/src/test/java/org/dromara/test/TagUnitTest.java                                                                               |   54 
 ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/core/SensitiveStrategy.java                                |   49 
 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/handler/TranslationHandler.java                   |   65 
 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java                            |   30 
 ruoyi-common/ruoyi-common-encrypt/pom.xml                                                                                                 |    4 
 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/page/TableDataInfo.java                                   |   81 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/StreamUtils.java                                               |  254 
 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisDecryptInterceptor.java                     |  112 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/bo/TestDemoImportVo.java                                                   |   53 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserException.java                                    |   20 
 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml                                                             |    4 
 ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/core/TencentSmsTemplate.java                                           |   82 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysLogininforServiceImpl.java                                    |  160 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysUserOnlineController.java                               |   91 
 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java                         |  198 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestI18nController.java                                                |   71 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/impl/package-info.java                                                    |    1 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPostServiceImpl.java                                          |  188 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisPubSubController.java                                             |   47 
 ruoyi-admin/src/main/java/org/dromara/DromaraApplication.java                                                                             |   23 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ThreadPoolConfig.java                                         |   57 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysOssBo.java                                                       |   49 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/TenantConstants.java                                        |   45 
 ruoyi-common/ruoyi-common-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports        |   12 
 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml                                                          |    2 
 ruoyi-common/ruoyi-common-job/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports         |    2 
 ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/factory/OssFactory.java                                                |   63 
 ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/notifier/CustomNotifier.java                                     |   40 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sql/SqlUtil.java                                               |   57 
 ruoyi-common/ruoyi-common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports         |    2 
 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/DictTypeTranslationImpl.java                 |   27 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java                                   |  123 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysRoleVo.java                                                      |  100 
 ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/properties/SmsProperties.java                                   |   45 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysPost.java                                                           |   51 
 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOssConfigMapper.xml                                                        |    2 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysOperLogMapper.java                                                  |   14 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/RouterVo.java                                                       |   62 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/mapper/TestDemoEncryptMapper.java                                                 |   13 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserRoleMapper.java                                                 |   17 
 ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/core/TenantSaTokenDao.java                                       |  148 
 ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/CacheUtils.java                                              |   75 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/DeviceType.java                                                |   32 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysTenantBo.java                                                    |  114 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysOssConfigController.java                                 |  105 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheConstants.java                                         |   25 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysLogininforController.java                               |   89 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/reflect/ReflectUtils.java                                      |   56 
 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/DefaultExcelListener.java                                     |  104 
 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/TranslationInterface.java                         |   20 
 ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/constant/GenConstants.java                                              |  186 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysDeptMapper.java                                                     |   46 
 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/annotation/DataPermission.java                                 |   18 
 ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/Mail.java                                                      |  486 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysOss.java                                                            |   50 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/GlobalException.java                                       |   53 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/MailController.java                                                    |   52 
 ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/config/GenConfig.java                                                   |   73 
 ruoyi-admin/src/main/resources/application.yml                                                                                            |   18 
 ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/OperatorType.java                                                |   23 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysDictDataController.java                                  |  117 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/CacheListInfoVo.java                                                |   23 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileSizeLimitExceededException.java                   |   18 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/file/MimeTypeUtils.java                                        |   40 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysRoleMapper.java                                                     |   68 
 ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/controller.java.vm                                                               |   22 
 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/InjectionMetaObjectHandler.java                        |   81 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/DeptService.java                                             |   18 
 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/CellMergeStrategy.java                                        |  114 
 ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/config/properties/SwaggerProperties.java                               |   94 
 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/ExcelResult.java                                              |   26 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/AvatarVo.java                                                       |   18 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysPostService.java                                                  |  106 
 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOssMapper.xml                                                              |    2 
 ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/controller/GenController.java                                           |  207 
 ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm                                                                   |    2 
 ruoyi-common/ruoyi-common-tenant/pom.xml                                                                                                  |    6 
 ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/bo.java.vm                                                                       |    6 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/TestDemoEncrypt.java                                                       |   29 
 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/core/I18nLocaleResolver.java                                           |   31 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/bo/TestTreeBo.java                                                         |   54 
 ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/annotation/RateLimiter.java                            |   41 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/mapper/package-info.java                                                          |    1 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysPostMapper.java                                                     |   32 
 ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/aspectj/RateLimiterAspect.java                         |  119 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/WeSocketController.java                                                |   33 
 ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/vo.java.vm                                                                       |    4 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDictTypeBo.java                                                  |   58 
 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/filter/RepeatableFilter.java                                           |   40 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantPackageController.java                             |  124 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSensitiveServiceImpl.java                                     |   26 
 ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/MailConfig.java                                               |   37 
 ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/mapper/GenTableMapper.java                                              |   58 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysOssConfigBo.java                                                 |  109 
 ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java                                                    |  245 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/properties/ThreadPoolProperties.java                          |   30 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/UserConstants.java                                          |  132 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/queue/BoundedQueueController.java                                      |   90 
 ruoyi-modules/ruoyi-job/pom.xml                                                                                                           |    6 
 ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/handler/AllUrlHandler.java                                   |   39 
 ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/domain/GenTable.java                                                    |  190 
 ruoyi-admin/src/test/java/org/dromara/test/DemoUnitTest.java                                                                              |   70 
 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/Base64Encryptor.java                            |   48 
 ruoyi-common/ruoyi-common-security/pom.xml                                                                                                |    4 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestEncryptController.java                                             |   55 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDictDataService.java                                              |   67 
 ruoyi-common/ruoyi-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports         |    2 
 ruoyi-common/ruoyi-common-log/pom.xml                                                                                                     |    6 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/file/FileUtils.java                                            |   43 
 ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/handler/BigNumberSerializer.java                                     |   42 
 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/config/properties/WebSocketProperties.java                 |   26 
 ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/QueueUtils.java                                              |  180 
 ruoyi-extend/ruoyi-monitor-admin/pom.xml                                                                                                  |    2 
 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelEnumConvert.java                                      |   75 
 ruoyi-common/ruoyi-common-ratelimiter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports |    2 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserProfileBo.java                                               |   55 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileException.java                                    |   21 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUserRole.java                                                       |   29 
 ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/util/VelocityInitializer.java                                           |   35 
 ruoyi-admin/src/main/java/org/dromara/web/domain/vo/CaptchaVo.java                                                                        |   25 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/SmsLoginBody.java                                       |   34 
 ruoyi-modules/ruoyi-generator/src/main/resources/generator.yml                                                                            |    8 
 ruoyi-extend/pom.xml                                                                                                                      |    2 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserExportVo.java                                                |   99 
 ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/properties/OssProperties.java                                          |   58 
 ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/config/SaTokenConfig.java                                      |   43 
 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/filter/XssFilter.java                                                  |   62 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/SmsController.java                                                     |   76 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysPermissionService.java                                            |   28 
 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/EncryptorManager.java                                     |   94 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDictTypeService.java                                              |   95 
 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/listener/WebSocketTopicListener.java                       |   38 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileNameLengthLimitExceededException.java             |   18 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/package-info.java                                                         |    1 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/runner/SystemApplicationRunner.java                                           |   28 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/AddressUtils.java                                           |   33 
 ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/manager/TenantSpringCacheManager.java                            |   32 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysRoleMenuMapper.java                                                 |   13 
 ruoyi-common/ruoyi-common-idempotent/src/main/java/org/dromara/common/idempotent/aspectj/RepeatSubmitAspect.java                          |  152 
 ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/core/SensitiveService.java                                 |   18 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/TenantStatus.java                                              |   30 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/queue/PriorityDemo.java                                                |   22 
 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysConfigMapper.xml                                                           |    2 
 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictTypeMapper.xml                                                         |    2 
 ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/InternalMailUtil.java                                          |  108 
 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/DefautExcelResult.java                                        |   73 
 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/annotation/DataColumn.java                                     |   28 
 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/interceptor/PlusWebSocketInterceptor.java                  |   51 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysTenantService.java                                                |   82 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysTenant.java                                                         |  103 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysTenantPackageVo.java                                             |   66 
 ruoyi-admin/pom.xml                                                                                                                       |   12 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/base/BaseException.java                                    |   79 
 ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java                                         |  172 
 ruoyi-common/pom.xml                                                                                                                      |    2 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestBatchController.java                                               |   90 
 ruoyi-common/ruoyi-common-job/pom.xml                                                                                                     |    4 
 /dev/null                                                                                                                                 |  525 
 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysNoticeMapper.xml                                                           |    2 
 ruoyi-common/ruoyi-common-idempotent/pom.xml                                                                                              |    6 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/OssService.java                                              |   18 
 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java                           |   46 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/listener/SysUserImportListener.java                                           |  119 
 513 files changed, 34,428 insertions(+), 800 deletions(-)

diff --git a/README.md b/README.md
index a47f51c..66eaab8 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
 ## 骞冲彴绠�浠�
 
 [![鐮佷簯Gitee](https://gitee.com/dromara/RuoYi-Vue-Plus/badge/star.svg?theme=blue)](https://gitee.com/dromara/RuoYi-Vue-Plus)
-[![GitHub](https://img.shields.io/github/stars/JavaLionLi/RuoYi-Vue-Plus.svg?style=social&label=Stars)](https://github.com/dromara/RuoYi-Vue-Plus)
+[![GitHub](https://img.shields.io/github/stars/dromara/RuoYi-Vue-Plus.svg?style=social&label=Stars)](https://github.com/dromara/RuoYi-Vue-Plus)
 [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://gitee.com/dromara/RuoYi-Vue-Plus/blob/master/LICENSE)
 [![浣跨敤IntelliJ IDEA寮�鍙戠淮鎶(https://img.shields.io/badge/IntelliJ%20IDEA-鎻愪緵鏀寔-blue.svg)](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
 <br>
@@ -19,7 +19,7 @@
 > 椤圭洰浠g爜銆佹枃妗� 鍧囧紑婧愬厤璐瑰彲鍟嗙敤 閬靛惊寮�婧愬崗璁湪椤圭洰涓繚鐣欏紑婧愬崗璁枃浠跺嵆鍙�<br>
 娲诲埌鑰佸啓鍒拌�� 涓哄叴瓒h�屽紑婧� 涓哄涔犺�屽紑婧� 涓鸿澶у鐪熸鍙互瀛﹀埌鎶�鏈�屽紑婧�
 
-> 绯荤粺婕旂ず: [浼犻�侀棬](https://javalionli.gitee.io/plus-doc/#/common/demo_system)
+> 绯荤粺婕旂ず: [浼犻�侀棬](https://plus-doc.dromara.org/#/common/demo_system)
 
 > 鍓嶇椤圭洰鍦板潃: [plus-ui](https://gitee.com/JavaLionLi/plus-ui)
 
@@ -27,7 +27,7 @@
 
 | 鍔熻兘          | 鏈鏋�                                                                                                               | RuoYi                                                                              |
 |-------------|-------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------|
-| 鍓嶇椤圭洰        | 鍩轰簬vue3-element-admin寮�婧愰」鐩噸鍐�<br/>Vue3 + TS + ElementPlus                                                            | 鍩轰簬Vue2/Vue3 + JS                                                                   | 
+| 鍓嶇椤圭洰        | 閲囩敤 Vue3 + TS + ElementPlus 閲嶅啓                                                                                     | 鍩轰簬Vue2/Vue3 + JS                                                                   | 
 | 鍚庣椤圭洰缁撴瀯      | 閲囩敤鎻掍欢鍖� + 鎵╁睍鍖呭舰寮� 缁撴瀯瑙h�� 鏄撲簬鎵╁睍                                                                                           | 妯″潡鐩镐簰娉ㄥ叆鑰﹀悎涓ラ噸闅句互鎵╁睍                                                                     | 
 | 鍚庣浠g爜椋庢牸      | 涓ユ牸閬靛畧Alibaba瑙勮寖涓庨」鐩粺涓�閰嶇疆鐨勪唬鐮佹牸寮忓寲                                                                                        | 浠g爜涔﹀啓涓庡父瑙勭粨鏋勪笉鍚岄槄璇婚殰纰嶅ぇ                                                                   |
 | Web瀹瑰櫒       | 閲囩敤 Undertow 鍩轰簬 XNIO 鐨勯珮鎬ц兘瀹瑰櫒                                                                                        | 閲囩敤 Tomcat                                                                          |
@@ -51,6 +51,7 @@
 | WebSocket鍗忚 | 鍩轰簬 Spring 灏佽鐨� WebSocket 鍗忚 鎵╁睍浜員oken閴存潈涓庡垎甯冨紡浼氳瘽鍚屾 涓嶅啀鍙槸鍩轰簬鍗曟満鐨勫簾鐗�                                                         | 鏃�                                                                                  |
 | 搴忓垪鍖�         | 閲囩敤 Jackson Spring瀹樻柟鍐呯疆搴忓垪鍖� 闈犺氨!!!                                                                                    | 閲囩敤 fastjson bugjson 杩滆繎闂诲悕                                                           | 
 | 鍒嗗竷寮忓箓绛�       | 鍙傝�冪編鍥TIS闃查噸绯荤粺绠�鍖栧疄鐜�(缁嗚妭鍙湅鏂囨。)                                                                                          | 鎵嬪姩缂栧啓娉ㄨВ鍩轰簬aop瀹炵幇                                                                      |
+| 鍒嗗竷寮忛攣        | 閲囩敤 Lock4j 搴曞眰鍩轰簬 Redisson                                                                                           | 鏃�                                                                                  |
 | 鍒嗗竷寮忎换鍔¤皟搴�     | 閲囩敤 Xxl-Job 澶╃敓鏀寔鍒嗗竷寮� 缁熶竴鐨勭鐞嗕腑蹇�                                                                                        | 閲囩敤 Quartz 鍩轰簬鏁版嵁搴撻攣鎬ц兘宸� 闆嗙兢闇�瑕佸仛寰堝閰嶇疆涓庢敼閫�                                                   | 
 | 鏂囦欢瀛樺偍        | 閲囩敤 Minio 鍒嗗竷寮忔枃浠跺瓨鍌� 澶╃敓鏀寔澶氭満銆佸纭洏銆佸鍒嗙墖銆佸鍓湰瀛樺偍<br/>鏀寔鏉冮檺绠$悊 瀹夊叏鍙潬 鏂囦欢鍙姞瀵嗗瓨鍌�                                                     | 閲囩敤 鏈満鏂囦欢瀛樺偍 鏂囦欢瑁告紡 鏄撲涪澶辨硠婕� 涓嶆敮鎸侀泦缇ゆ湁鍗曠偣鏁堝簲                                                    |
 | 浜戝瓨鍌�         | 閲囩敤 AWS S3 鍗忚瀹㈡埛绔� 鏀寔 涓冪墰銆侀樋閲屻�佽吘璁� 绛変竴鍒囨敮鎸丼3鍗忚鐨勫巶瀹�                                                                          | 涓嶆敮鎸�                                                                                |
@@ -101,17 +102,17 @@
 
 浣跨敤妗嗘灦鍓嶈浠旂粏闃呰鏂囨。閲嶇偣娉ㄦ剰浜嬮」
 <br>
->[鍒濆鍖栭」鐩� 蹇呯湅](https://javalionli.gitee.io/plus-doc/#/ruoyi-vue-plus/quickstart/init)
->>[https://javalionli.gitee.io/plus-doc/#/ruoyi-vue-plus/quickstart/init](https://javalionli.gitee.io/plus-doc/#/ruoyi-vue-plus/quickstart/init)
+>[鍒濆鍖栭」鐩� 蹇呯湅](https://plus-doc.dromara.org/#/ruoyi-vue-plus/quickstart/init)
+>>[https://plus-doc.dromara.org/#/ruoyi-vue-plus/quickstart/init](https://plus-doc.dromara.org/#/ruoyi-vue-plus/quickstart/init)
 >
->[涓撴爮涓庤棰� 鍏ラ棬蹇呯湅](https://javalionli.gitee.io/plus-doc/#/common/column)
->>[https://javalionli.gitee.io/plus-doc/#/common/column](https://javalionli.gitee.io/plus-doc/#/common/column)
+>[涓撴爮涓庤棰� 鍏ラ棬蹇呯湅](https://plus-doc.dromara.org/#/common/column)
+>>[https://plus-doc.dromara.org/#/common/column](https://plus-doc.dromara.org/#/common/column)
 >
->[閮ㄧ讲椤圭洰 蹇呯湅](https://javalionli.gitee.io/plus-doc/#/ruoyi-vue-plus/quickstart/deploy)
->>[https://javalionli.gitee.io/plus-doc/#/ruoyi-vue-plus/quickstart/deploy](https://javalionli.gitee.io/plus-doc/#/ruoyi-vue-plus/quickstart/deploy)
+>[閮ㄧ讲椤圭洰 蹇呯湅](https://plus-doc.dromara.org/#/ruoyi-vue-plus/quickstart/deploy)
+>>[https://plus-doc.dromara.org/#/ruoyi-vue-plus/quickstart/deploy](https://plus-doc.dromara.org/#/ruoyi-vue-plus/quickstart/deploy)
 > 
->[鍙傝�冩枃妗� Wiki](https://javalionli.gitee.io/plus-doc)
->>[https://javalionli.gitee.io/plus-doc](https://javalionli.gitee.io/plus-doc)
+>[鍙傝�冩枃妗� Wiki](https://plus-doc.dromara.org)
+>>[https://plus-doc.dromara.org](https://plus-doc.dromara.org)
 
 ## 杞欢鏋舵瀯鍥�
 
@@ -119,7 +120,7 @@
 
 ## 濡備綍鍙備笌璐$尞
 
-[鍙備笌璐$尞鐨勬柟寮� https://javalionli.gitee.io/plus-doc/#/common/contribution](https://javalionli.gitee.io/plus-doc/#/common/contribution)
+[鍙備笌璐$尞鐨勬柟寮� https://plus-doc.dromara.org/#/common/contribution](https://plus-doc.dromara.org/#/common/contribution)
 
 ### 鍏朵粬
 
@@ -127,16 +128,16 @@
 * GitHub 鍦板潃 [RuoYi-Vue-Plus](https://github.com/dromara/RuoYi-Vue-Plus)
 * 寰湇鍔� 鍒嗘敮 [RuoYi-Cloud-Plus](https://gitee.com/JavaLionLi/RuoYi-Cloud-Plus)
 * 鍓嶇椤圭洰 鍦板潃 [plus-ui](https://gitee.com/JavaLionLi/plus-ui)
-* 鐢ㄦ埛鎵╁睍椤圭洰 [鎵╁睍椤圭洰鍒楄〃](https://javalionli.gitee.io/plus-doc/#/ruoyi-vue-plus/extend-project/list)
+* 鐢ㄦ埛鎵╁睍椤圭洰 [鎵╁睍椤圭洰鍒楄〃](https://plus-doc.dromara.org/#/ruoyi-vue-plus/extend-project/list)
 
 ## 鍔犵兢涓庢崘鐚�
->[鍔犵兢涓庢崘鐚甝(https://javalionli.gitee.io/plus-doc/#/ruoyi-vue-plus/other/group_chat)
->>[https://javalionli.gitee.io/plus-doc/#/ruoyi-vue-plus/other/group_chat](https://javalionli.gitee.io/plus-doc/#/ruoyi-vue-plus/other/group_chat)
+>[鍔犵兢涓庢崘鐚甝(https://plus-doc.dromara.org/#/ruoyi-vue-plus/other/group_chat)
+>>[https://plus-doc.dromara.org/#/ruoyi-vue-plus/other/group_chat](https://plus-doc.dromara.org/#/ruoyi-vue-plus/other/group_chat)
 
 ## 鎹愮尞浣滆��
 浣滆�呬负鍏艰亴鍋氬紑婧�,骞虫椂杩橀渶瑕佸伐浣�,濡傛灉甯埌浜嗘偍鍙互璇蜂綔鑰呭悆涓洅楗�  
-<img src="https://images.gitee.com/uploads/images/2022/0218/213734_b1b8197f_1766278.jpeg" width="300px" height="450px" />
-<img src="https://images.gitee.com/uploads/images/2021/0525/101713_3d18b119_1766278.jpeg" width="300px" height="450px" />
+<img src="https://foruda.gitee.com/images/1678975784848381069/d8661ed9_1766278.png" width="300px" height="450px" />
+<img src="https://foruda.gitee.com/images/1678975801230205215/6f96229d_1766278.png" width="300px" height="450px" />
 
 ## 婕旂ず鍥句緥
 
diff --git a/pom.xml b/pom.xml
index 2c03e82..690409e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
-    <groupId>com.ruoyi</groupId>
+    <groupId>org.dromara</groupId>
     <artifactId>ruoyi-vue-plus</artifactId>
     <version>${revision}</version>
 
@@ -113,7 +113,7 @@
 
             <!-- common 鐨勪緷璧栭厤缃�-->
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-common-bom</artifactId>
                 <version>${revision}</version>
                 <type>pom</type>
@@ -312,25 +312,25 @@
             </dependency>
 
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-system</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-job</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-generator</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-demo</artifactId>
                 <version>${revision}</version>
             </dependency>
diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml
index c792d02..06e31b0 100644
--- a/ruoyi-admin/pom.xml
+++ b/ruoyi-admin/pom.xml
@@ -4,7 +4,7 @@
          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>
+        <groupId>org.dromara</groupId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
@@ -40,29 +40,29 @@
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-doc</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-system</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-job</artifactId>
         </dependency>
 
         <!-- 浠g爜鐢熸垚-->
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-generator</artifactId>
         </dependency>
 
         <!--  demo妯″潡  -->
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-demo</artifactId>
         </dependency>
 
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
deleted file mode 100644
index 77a2763..0000000
--- a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.ruoyi;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
-
-/**
- * 鍚姩绋嬪簭
- *
- * @author ruoyi
- */
-
-@SpringBootApplication
-public class RuoYiApplication {
-
-    public static void main(String[] 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/RuoYiServletInitializer.java b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiServletInitializer.java
deleted file mode 100644
index dd05626..0000000
--- a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiServletInitializer.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.ruoyi;
-
-import org.springframework.boot.builder.SpringApplicationBuilder;
-import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
-
-/**
- * web瀹瑰櫒涓繘琛岄儴缃�
- *
- * @author ruoyi
- */
-public class RuoYiServletInitializer extends SpringBootServletInitializer {
-
-    @Override
-    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
-        return application.sources(RuoYiApplication.class);
-    }
-
-}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/AuthController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/AuthController.java
deleted file mode 100644
index 12cf1fe..0000000
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/AuthController.java
+++ /dev/null
@@ -1,153 +0,0 @@
-package com.ruoyi.web.controller;
-
-import cn.dev33.satoken.annotation.SaIgnore;
-import cn.hutool.core.collection.CollUtil;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.core.domain.model.EmailLoginBody;
-import com.ruoyi.common.core.domain.model.LoginBody;
-import com.ruoyi.common.core.domain.model.RegisterBody;
-import com.ruoyi.common.core.domain.model.SmsLoginBody;
-import com.ruoyi.common.core.utils.MapstructUtils;
-import com.ruoyi.common.core.utils.StreamUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.tenant.helper.TenantHelper;
-import com.ruoyi.system.domain.bo.SysTenantBo;
-import com.ruoyi.system.domain.vo.SysTenantVo;
-import com.ruoyi.system.service.ISysConfigService;
-import com.ruoyi.system.service.ISysTenantService;
-import com.ruoyi.web.domain.vo.LoginTenantVo;
-import com.ruoyi.web.domain.vo.LoginVo;
-import com.ruoyi.web.domain.vo.TenantListVo;
-import com.ruoyi.web.service.SysLoginService;
-import com.ruoyi.web.service.SysRegisterService;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.validation.constraints.NotBlank;
-import lombok.RequiredArgsConstructor;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.net.URL;
-import java.util.List;
-
-/**
- * 璁よ瘉
- *
- * @author Lion Li
- */
-@SaIgnore
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/auth")
-public class AuthController {
-
-    private final SysLoginService loginService;
-    private final SysRegisterService registerService;
-    private final ISysConfigService configService;
-    private final ISysTenantService tenantService;
-
-    /**
-     * 鐧诲綍鏂规硶
-     *
-     * @param body 鐧诲綍淇℃伅
-     * @return 缁撴灉
-     */
-    @PostMapping("/login")
-    public R<LoginVo> login(@Validated @RequestBody LoginBody body) {
-        LoginVo loginVo = new LoginVo();
-        // 鐢熸垚浠ょ墝
-        String token = loginService.login(
-                body.getTenantId(),
-                body.getUsername(), body.getPassword(),
-                body.getCode(), body.getUuid());
-        loginVo.setToken(token);
-        return R.ok(loginVo);
-    }
-
-    /**
-     * 鐭俊鐧诲綍
-     *
-     * @param body 鐧诲綍淇℃伅
-     * @return 缁撴灉
-     */
-    @PostMapping("/smsLogin")
-    public R<LoginVo> smsLogin(@Validated @RequestBody SmsLoginBody body) {
-        LoginVo loginVo = new LoginVo();
-        // 鐢熸垚浠ょ墝
-        String token = loginService.smsLogin(body.getTenantId(), body.getPhonenumber(), body.getSmsCode());
-        loginVo.setToken(token);
-        return R.ok(loginVo);
-    }
-
-    /**
-     * 閭欢鐧诲綍
-     *
-     * @param body 鐧诲綍淇℃伅
-     * @return 缁撴灉
-     */
-    @PostMapping("/emailLogin")
-    public R<LoginVo> emailLogin(@Validated @RequestBody EmailLoginBody body) {
-        LoginVo loginVo = new LoginVo();
-        // 鐢熸垚浠ょ墝
-        String token = loginService.emailLogin(body.getTenantId(), body.getEmail(), body.getEmailCode());
-        loginVo.setToken(token);
-        return R.ok(loginVo);
-    }
-
-    /**
-     * 灏忕▼搴忕櫥褰�(绀轰緥)
-     *
-     * @param xcxCode 灏忕▼搴廲ode
-     * @return 缁撴灉
-     */
-    @PostMapping("/xcxLogin")
-    public R<LoginVo> xcxLogin(@NotBlank(message = "{xcx.code.not.blank}") String xcxCode) {
-        LoginVo loginVo = new LoginVo();
-        // 鐢熸垚浠ょ墝
-        String token = loginService.xcxLogin(xcxCode);
-        loginVo.setToken(token);
-        return R.ok(loginVo);
-    }
-
-    /**
-     * 閫�鍑虹櫥褰�
-     */
-    @PostMapping("/logout")
-    public R<Void> logout() {
-        loginService.logout();
-        return R.ok("閫�鍑烘垚鍔�");
-    }
-
-    /**
-     * 鐢ㄦ埛娉ㄥ唽
-     */
-    @PostMapping("/register")
-    public R<Void> register(@Validated @RequestBody RegisterBody user) {
-        if (!configService.selectRegisterEnabled(user.getTenantId())) {
-            return R.fail("褰撳墠绯荤粺娌℃湁寮�鍚敞鍐屽姛鑳斤紒");
-        }
-        registerService.register(user);
-        return R.ok();
-    }
-
-    /**
-     * 鐧诲綍椤甸潰绉熸埛涓嬫媺妗�
-     *
-     * @return 绉熸埛鍒楄〃
-     */
-    @GetMapping("/tenant/list")
-    public R<LoginTenantVo> tenantList(HttpServletRequest request) throws Exception {
-        List<SysTenantVo> tenantList = tenantService.queryList(new SysTenantBo());
-        List<TenantListVo> voList = MapstructUtils.convert(tenantList, TenantListVo.class);
-        // 鑾峰彇鍩熷悕
-        String host = new URL(request.getRequestURL().toString()).getHost();
-        // 鏍规嵁鍩熷悕杩涜绛涢��
-        List<TenantListVo> list = StreamUtils.filter(voList, vo -> StringUtils.equals(vo.getDomain(), host));
-        // 杩斿洖瀵硅薄
-        LoginTenantVo vo = new LoginTenantVo();
-        vo.setVoList(CollUtil.isNotEmpty(list) ? list : voList);
-        vo.setTenantEnabled(TenantHelper.isEnable());
-        return R.ok(vo);
-    }
-
-}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/CaptchaController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/CaptchaController.java
deleted file mode 100644
index 757caf5..0000000
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/CaptchaController.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package com.ruoyi.web.controller;
-
-import cn.dev33.satoken.annotation.SaIgnore;
-import cn.hutool.captcha.AbstractCaptcha;
-import cn.hutool.captcha.generator.CodeGenerator;
-import cn.hutool.core.util.IdUtil;
-import cn.hutool.core.util.RandomUtil;
-import com.ruoyi.common.core.constant.Constants;
-import com.ruoyi.common.core.constant.GlobalConstants;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.core.utils.SpringUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.core.utils.reflect.ReflectUtils;
-import com.ruoyi.common.mail.config.properties.MailProperties;
-import com.ruoyi.common.mail.utils.MailUtils;
-import com.ruoyi.common.redis.utils.RedisUtils;
-import com.ruoyi.common.sms.config.properties.SmsProperties;
-import com.ruoyi.common.sms.core.SmsTemplate;
-import com.ruoyi.common.sms.entity.SmsResult;
-import com.ruoyi.common.web.config.properties.CaptchaProperties;
-import com.ruoyi.common.web.enums.CaptchaType;
-import com.ruoyi.web.domain.vo.CaptchaVo;
-import jakarta.validation.constraints.NotBlank;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.expression.Expression;
-import org.springframework.expression.ExpressionParser;
-import org.springframework.expression.spel.standard.SpelExpressionParser;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.time.Duration;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * 楠岃瘉鐮佹搷浣滃鐞�
- *
- * @author Lion Li
- */
-@SaIgnore
-@Slf4j
-@Validated
-@RequiredArgsConstructor
-@RestController
-public class CaptchaController {
-
-    private final CaptchaProperties captchaProperties;
-    private final SmsProperties smsProperties;
-    private final MailProperties mailProperties;
-
-    /**
-     * 鐭俊楠岃瘉鐮�
-     *
-     * @param phonenumber 鐢ㄦ埛鎵嬫満鍙�
-     */
-    @GetMapping("/sms/code")
-    public R<Void> smsCode(@NotBlank(message = "{user.phonenumber.not.blank}") String phonenumber) {
-        if (!smsProperties.getEnabled()) {
-            return R.fail("褰撳墠绯荤粺娌℃湁寮�鍚煭淇″姛鑳斤紒");
-        }
-        String key = GlobalConstants.CAPTCHA_CODE_KEY + phonenumber;
-        String code = RandomUtil.randomNumbers(4);
-        RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
-        // 楠岃瘉鐮佹ā鏉縤d 鑷澶勭悊 (鏌ユ暟鎹簱鎴栧啓姝诲潎鍙�)
-        String templateId = "";
-        Map<String, String> map = new HashMap<>(1);
-        map.put("code", code);
-        SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class);
-        SmsResult result = smsTemplate.send(phonenumber, templateId, map);
-        if (!result.isSuccess()) {
-            log.error("楠岃瘉鐮佺煭淇″彂閫佸紓甯� => {}", result);
-            return R.fail(result.getMessage());
-        }
-        return R.ok();
-    }
-
-    /**
-     * 閭楠岃瘉鐮�
-     *
-     * @param email 閭
-     */
-    @GetMapping("/email/code")
-    public R<Void> emailCode(@NotBlank(message = "{user.email.not.blank}") String email) {
-        if (!mailProperties.getEnabled()) {
-            return R.fail("褰撳墠绯荤粺娌℃湁寮�鍚偖绠卞姛鑳斤紒");
-        }
-        String key = GlobalConstants.CAPTCHA_CODE_KEY + email;
-        String code = RandomUtil.randomNumbers(4);
-        RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
-        try {
-            MailUtils.sendText(email, "鐧诲綍楠岃瘉鐮�", "鎮ㄦ湰娆¢獙璇佺爜涓猴細" + code + "锛屾湁鏁堟�т负" + Constants.CAPTCHA_EXPIRATION + "鍒嗛挓锛岃灏藉揩濉啓銆�");
-        } catch (Exception e) {
-            log.error("楠岃瘉鐮佺煭淇″彂閫佸紓甯� => {}", e.getMessage());
-            return R.fail(e.getMessage());
-        }
-        return R.ok();
-    }
-
-    /**
-     * 鐢熸垚楠岃瘉鐮�
-     */
-    @GetMapping("/code")
-    public R<CaptchaVo> getCode() {
-        CaptchaVo captchaVo = new CaptchaVo();
-        boolean captchaEnabled = captchaProperties.getEnable();
-        if (!captchaEnabled) {
-            captchaVo.setCaptchaEnabled(false);
-            return R.ok(captchaVo);
-        }
-        // 淇濆瓨楠岃瘉鐮佷俊鎭�
-        String uuid = IdUtil.simpleUUID();
-        String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + uuid;
-        // 鐢熸垚楠岃瘉鐮�
-        CaptchaType captchaType = captchaProperties.getType();
-        boolean isMath = CaptchaType.MATH == captchaType;
-        Integer length = isMath ? captchaProperties.getNumberLength() : captchaProperties.getCharLength();
-        CodeGenerator codeGenerator = ReflectUtils.newInstance(captchaType.getClazz(), length);
-        AbstractCaptcha captcha = SpringUtils.getBean(captchaProperties.getCategory().getClazz());
-        captcha.setGenerator(codeGenerator);
-        captcha.createCode();
-        String code = captcha.getCode();
-        if (isMath) {
-            ExpressionParser parser = new SpelExpressionParser();
-            Expression exp = parser.parseExpression(StringUtils.remove(code, "="));
-            code = exp.getValue(String.class);
-        }
-        RedisUtils.setCacheObject(verifyKey, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
-        captchaVo.setUuid(uuid);
-        captchaVo.setImg(captcha.getImageBase64());
-        return R.ok(captchaVo);
-    }
-
-}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/IndexController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/IndexController.java
deleted file mode 100644
index 2139240..0000000
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/IndexController.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.ruoyi.web.controller;
-
-import cn.dev33.satoken.annotation.SaIgnore;
-import com.ruoyi.common.core.config.RuoYiConfig;
-import com.ruoyi.common.core.utils.StringUtils;
-import lombok.RequiredArgsConstructor;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * 棣栭〉
- *
- * @author Lion Li
- */
-@SaIgnore
-@RequiredArgsConstructor
-@RestController
-public class IndexController {
-
-    /**
-     * 绯荤粺鍩虹閰嶇疆
-     */
-    private final RuoYiConfig ruoyiConfig;
-
-    /**
-     * 璁块棶棣栭〉锛屾彁绀鸿
-     */
-    @GetMapping("/")
-    public String index() {
-        return StringUtils.format("娆㈣繋浣跨敤{}鍚庡彴绠$悊妗嗘灦锛屽綋鍓嶇増鏈細v{}锛岃閫氳繃鍓嶇鍦板潃璁块棶銆�", ruoyiConfig.getName(), ruoyiConfig.getVersion());
-    }
-}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/domain/vo/CaptchaVo.java b/ruoyi-admin/src/main/java/com/ruoyi/web/domain/vo/CaptchaVo.java
deleted file mode 100644
index 8c717f0..0000000
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/domain/vo/CaptchaVo.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.ruoyi.web.domain.vo;
-
-import lombok.Data;
-
-/**
- * 楠岃瘉鐮佷俊鎭�
- *
- * @author Michelle.Chung
- */
-@Data
-public class CaptchaVo {
-
-    /**
-     * 鏄惁寮�鍚獙璇佺爜
-     */
-    private Boolean captchaEnabled = true;
-
-    private String uuid;
-
-    /**
-     * 楠岃瘉鐮佸浘鐗�
-     */
-    private String img;
-
-}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/domain/vo/LoginTenantVo.java b/ruoyi-admin/src/main/java/com/ruoyi/web/domain/vo/LoginTenantVo.java
deleted file mode 100644
index cc42e96..0000000
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/domain/vo/LoginTenantVo.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.ruoyi.web.domain.vo;
-
-import lombok.Data;
-
-import java.util.List;
-
-/**
- * 鐧诲綍绉熸埛瀵硅薄
- *
- * @author Michelle.Chung
- */
-@Data
-public class LoginTenantVo {
-
-    /**
-     * 绉熸埛寮�鍏�
-     */
-    private Boolean tenantEnabled;
-
-    /**
-     * 绉熸埛瀵硅薄鍒楄〃
-     */
-    private List<TenantListVo> voList;
-
-}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/domain/vo/LoginVo.java b/ruoyi-admin/src/main/java/com/ruoyi/web/domain/vo/LoginVo.java
deleted file mode 100644
index 387ed7b..0000000
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/domain/vo/LoginVo.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.ruoyi.web.domain.vo;
-
-import lombok.Data;
-
-/**
- * 鐧诲綍楠岃瘉淇℃伅
- *
- * @author Michelle.Chung
- */
-@Data
-public class LoginVo {
-
-    private String token;
-
-}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/domain/vo/TenantListVo.java b/ruoyi-admin/src/main/java/com/ruoyi/web/domain/vo/TenantListVo.java
deleted file mode 100644
index e3da6c7..0000000
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/domain/vo/TenantListVo.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.ruoyi.web.domain.vo;
-
-import com.ruoyi.system.domain.vo.SysTenantVo;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-/**
- * 绉熸埛鍒楄〃
- *
- * @author Lion Li
- */
-@Data
-@AutoMapper(target = SysTenantVo.class)
-public class TenantListVo {
-
-    private String tenantId;
-
-    private String companyName;
-
-    private String domain;
-
-}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/service/SysLoginService.java b/ruoyi-admin/src/main/java/com/ruoyi/web/service/SysLoginService.java
deleted file mode 100644
index 3b8a1c6..0000000
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/service/SysLoginService.java
+++ /dev/null
@@ -1,390 +0,0 @@
-package com.ruoyi.web.service;
-
-import cn.dev33.satoken.exception.NotLoginException;
-import cn.dev33.satoken.secure.BCrypt;
-import cn.dev33.satoken.stp.StpUtil;
-import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.util.ObjectUtil;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.ruoyi.common.core.constant.Constants;
-import com.ruoyi.common.core.constant.GlobalConstants;
-import com.ruoyi.common.core.constant.TenantConstants;
-import com.ruoyi.common.core.domain.dto.RoleDTO;
-import com.ruoyi.common.core.domain.model.LoginUser;
-import com.ruoyi.common.core.domain.model.XcxLoginUser;
-import com.ruoyi.common.core.enums.DeviceType;
-import com.ruoyi.common.core.enums.LoginType;
-import com.ruoyi.common.core.enums.TenantStatus;
-import com.ruoyi.common.core.enums.UserStatus;
-import com.ruoyi.common.core.exception.user.CaptchaException;
-import com.ruoyi.common.core.exception.user.CaptchaExpireException;
-import com.ruoyi.common.core.exception.user.UserException;
-import com.ruoyi.common.core.utils.*;
-import com.ruoyi.common.log.event.LogininforEvent;
-import com.ruoyi.common.redis.utils.RedisUtils;
-import com.ruoyi.common.satoken.utils.LoginHelper;
-import com.ruoyi.common.tenant.exception.TenantException;
-import com.ruoyi.common.tenant.helper.TenantHelper;
-import com.ruoyi.common.web.config.properties.CaptchaProperties;
-import com.ruoyi.system.domain.SysUser;
-import com.ruoyi.system.domain.vo.SysTenantVo;
-import com.ruoyi.system.domain.vo.SysUserVo;
-import com.ruoyi.system.mapper.SysUserMapper;
-import com.ruoyi.system.service.ISysPermissionService;
-import com.ruoyi.system.service.ISysTenantService;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Service;
-
-import java.time.Duration;
-import java.util.Date;
-import java.util.List;
-import java.util.function.Supplier;
-
-/**
- * 鐧诲綍鏍¢獙鏂规硶
- *
- * @author Lion Li
- */
-@RequiredArgsConstructor
-@Slf4j
-@Service
-public class SysLoginService {
-
-    private final SysUserMapper userMapper;
-    private final CaptchaProperties captchaProperties;
-    private final ISysPermissionService permissionService;
-    private final ISysTenantService tenantService;
-
-    @Value("${user.password.maxRetryCount}")
-    private Integer maxRetryCount;
-
-    @Value("${user.password.lockTime}")
-    private Integer lockTime;
-
-    /**
-     * 鐧诲綍楠岃瘉
-     *
-     * @param username 鐢ㄦ埛鍚�
-     * @param password 瀵嗙爜
-     * @param code     楠岃瘉鐮�
-     * @param uuid     鍞竴鏍囪瘑
-     * @return 缁撴灉
-     */
-    public String login(String tenantId, String username, String password, String code, String uuid) {
-        boolean captchaEnabled = captchaProperties.getEnable();
-        // 楠岃瘉鐮佸紑鍏�
-        if (captchaEnabled) {
-            validateCaptcha(tenantId, username, code, uuid);
-        }
-        // 鏍¢獙绉熸埛
-        checkTenant(tenantId);
-
-        SysUserVo user = loadUserByUsername(tenantId, username);
-        checkLogin(LoginType.PASSWORD, tenantId, username, () -> !BCrypt.checkpw(password, user.getPassword()));
-        // 姝ゅ鍙牴鎹櫥褰曠敤鎴风殑鏁版嵁涓嶅悓 鑷鍒涘缓 loginUser
-        LoginUser loginUser = buildLoginUser(user);
-        // 鐢熸垚token
-        LoginHelper.loginByDevice(loginUser, DeviceType.PC);
-
-        recordLogininfor(loginUser.getTenantId(), username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
-        recordLoginInfo(user.getUserId());
-        return StpUtil.getTokenValue();
-    }
-
-    public String smsLogin(String tenantId, String phonenumber, String smsCode) {
-        // 鏍¢獙绉熸埛
-        checkTenant(tenantId);
-        // 閫氳繃鎵嬫満鍙锋煡鎵剧敤鎴�
-        SysUserVo user = loadUserByPhonenumber(tenantId, phonenumber);
-
-        checkLogin(LoginType.SMS, tenantId, user.getUserName(), () -> !validateSmsCode(tenantId, phonenumber, smsCode));
-        // 姝ゅ鍙牴鎹櫥褰曠敤鎴风殑鏁版嵁涓嶅悓 鑷鍒涘缓 loginUser
-        LoginUser loginUser = buildLoginUser(user);
-        // 鐢熸垚token
-        LoginHelper.loginByDevice(loginUser, DeviceType.APP);
-
-        recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
-        recordLoginInfo(user.getUserId());
-        return StpUtil.getTokenValue();
-    }
-
-    public String emailLogin(String tenantId, String email, String emailCode) {
-        // 鏍¢獙绉熸埛
-        checkTenant(tenantId);
-        // 閫氳繃鎵嬫満鍙锋煡鎵剧敤鎴�
-        SysUserVo user = loadUserByEmail(tenantId, email);
-
-        checkLogin(LoginType.EMAIL, tenantId, user.getUserName(), () -> !validateEmailCode(tenantId, email, emailCode));
-        // 姝ゅ鍙牴鎹櫥褰曠敤鎴风殑鏁版嵁涓嶅悓 鑷鍒涘缓 loginUser
-        LoginUser loginUser = buildLoginUser(user);
-        // 鐢熸垚token
-        LoginHelper.loginByDevice(loginUser, DeviceType.APP);
-
-        recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
-        recordLoginInfo(user.getUserId());
-        return StpUtil.getTokenValue();
-    }
-
-
-    public String xcxLogin(String xcxCode) {
-        // xcxCode 涓� 灏忕▼搴忚皟鐢� wx.login 鎺堟潈鍚庤幏鍙�
-        // todo 浠ヤ笅鑷瀹炵幇
-        // 鏍¢獙 appid + appsrcret + xcxCode 璋冪敤鐧诲綍鍑瘉鏍¢獙鎺ュ彛 鑾峰彇 session_key 涓� openid
-        String openid = "";
-        SysUserVo user = loadUserByOpenid(openid);
-        // 鏍¢獙绉熸埛
-        checkTenant(user.getTenantId());
-
-        // 姝ゅ鍙牴鎹櫥褰曠敤鎴风殑鏁版嵁涓嶅悓 鑷鍒涘缓 loginUser
-        XcxLoginUser loginUser = new XcxLoginUser();
-        loginUser.setTenantId(user.getTenantId());
-        loginUser.setUserId(user.getUserId());
-        loginUser.setUsername(user.getUserName());
-        loginUser.setUserType(user.getUserType());
-        loginUser.setOpenid(openid);
-        // 鐢熸垚token
-        LoginHelper.loginByDevice(loginUser, DeviceType.XCX);
-
-        recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
-        recordLoginInfo(user.getUserId());
-        return StpUtil.getTokenValue();
-    }
-
-    /**
-     * 閫�鍑虹櫥褰�
-     */
-    public void logout() {
-        try {
-            LoginUser loginUser = LoginHelper.getLoginUser();
-            if (TenantHelper.isEnable() && LoginHelper.isSuperAdmin()) {
-                // 瓒呯骇绠$悊鍛� 鐧诲嚭娓呴櫎鍔ㄦ�佺鎴�
-                TenantHelper.clearDynamic();
-            }
-            StpUtil.logout();
-            recordLogininfor(loginUser.getTenantId(), loginUser.getUsername(), Constants.LOGOUT, MessageUtils.message("user.logout.success"));
-        } catch (NotLoginException ignored) {
-        }
-    }
-
-    /**
-     * 璁板綍鐧诲綍淇℃伅
-     *
-     * @param tenantId 绉熸埛ID
-     * @param username 鐢ㄦ埛鍚�
-     * @param status   鐘舵��
-     * @param message  娑堟伅鍐呭
-     */
-    private void recordLogininfor(String tenantId, String username, String status, String message) {
-        LogininforEvent logininforEvent = new LogininforEvent();
-        logininforEvent.setTenantId(tenantId);
-        logininforEvent.setUsername(username);
-        logininforEvent.setStatus(status);
-        logininforEvent.setMessage(message);
-        logininforEvent.setRequest(ServletUtils.getRequest());
-        SpringUtils.context().publishEvent(logininforEvent);
-    }
-
-    /**
-     * 鏍¢獙鐭俊楠岃瘉鐮�
-     */
-    private boolean validateSmsCode(String tenantId, String phonenumber, String smsCode) {
-        String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + phonenumber);
-        if (StringUtils.isBlank(code)) {
-            recordLogininfor(tenantId, phonenumber, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
-            throw new CaptchaExpireException();
-        }
-        return code.equals(smsCode);
-    }
-
-    /**
-     * 鏍¢獙閭楠岃瘉鐮�
-     */
-    private boolean validateEmailCode(String tenantId, String email, String emailCode) {
-        String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + email);
-        if (StringUtils.isBlank(code)) {
-            recordLogininfor(tenantId, email, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
-            throw new CaptchaExpireException();
-        }
-        return code.equals(emailCode);
-    }
-
-    /**
-     * 鏍¢獙楠岃瘉鐮�
-     *
-     * @param username 鐢ㄦ埛鍚�
-     * @param code     楠岃瘉鐮�
-     * @param uuid     鍞竴鏍囪瘑
-     */
-    public void validateCaptcha(String tenantId, String username, String code, String uuid) {
-        String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
-        String captcha = RedisUtils.getCacheObject(verifyKey);
-        RedisUtils.deleteObject(verifyKey);
-        if (captcha == null) {
-            recordLogininfor(tenantId, username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
-            throw new CaptchaExpireException();
-        }
-        if (!code.equalsIgnoreCase(captcha)) {
-            recordLogininfor(tenantId, username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"));
-            throw new CaptchaException();
-        }
-    }
-
-    private SysUserVo loadUserByUsername(String tenantId, String username) {
-        SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
-                .select(SysUser::getUserName, SysUser::getStatus)
-                .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId)
-                .eq(SysUser::getUserName, username));
-        if (ObjectUtil.isNull(user)) {
-            log.info("鐧诲綍鐢ㄦ埛锛歿} 涓嶅瓨鍦�.", username);
-            throw new UserException("user.not.exists", username);
-        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
-            log.info("鐧诲綍鐢ㄦ埛锛歿} 宸茶鍋滅敤.", username);
-            throw new UserException("user.blocked", username);
-        }
-        if (TenantHelper.isEnable()) {
-            return userMapper.selectTenantUserByUserName(username, tenantId);
-        }
-        return userMapper.selectUserByUserName(username);
-    }
-
-    private SysUserVo loadUserByPhonenumber(String tenantId, String phonenumber) {
-        SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
-                .select(SysUser::getPhonenumber, SysUser::getStatus)
-                .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId)
-                .eq(SysUser::getPhonenumber, phonenumber));
-        if (ObjectUtil.isNull(user)) {
-            log.info("鐧诲綍鐢ㄦ埛锛歿} 涓嶅瓨鍦�.", phonenumber);
-            throw new UserException("user.not.exists", phonenumber);
-        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
-            log.info("鐧诲綍鐢ㄦ埛锛歿} 宸茶鍋滅敤.", phonenumber);
-            throw new UserException("user.blocked", phonenumber);
-        }
-        if (TenantHelper.isEnable()) {
-            return userMapper.selectTenantUserByPhonenumber(phonenumber, tenantId);
-        }
-        return userMapper.selectUserByPhonenumber(phonenumber);
-    }
-
-    private SysUserVo loadUserByEmail(String tenantId, String email) {
-        SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
-            .select(SysUser::getPhonenumber, SysUser::getStatus)
-            .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId)
-            .eq(SysUser::getEmail, email));
-        if (ObjectUtil.isNull(user)) {
-            log.info("鐧诲綍鐢ㄦ埛锛歿} 涓嶅瓨鍦�.", email);
-            throw new UserException("user.not.exists", email);
-        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
-            log.info("鐧诲綍鐢ㄦ埛锛歿} 宸茶鍋滅敤.", email);
-            throw new UserException("user.blocked", email);
-        }
-        if (TenantHelper.isEnable()) {
-            return userMapper.selectTenantUserByEmail(email, tenantId);
-        }
-        return userMapper.selectUserByEmail(email);
-    }
-
-    private SysUserVo loadUserByOpenid(String openid) {
-        // 浣跨敤 openid 鏌ヨ缁戝畾鐢ㄦ埛 濡傛湭缁戝畾鐢ㄦ埛 鍒欐牴鎹笟鍔¤嚜琛屽鐞� 渚嬪 鍒涘缓榛樿鐢ㄦ埛
-        // todo 鑷瀹炵幇 userService.selectUserByOpenid(openid);
-        SysUserVo user = new SysUserVo();
-        if (ObjectUtil.isNull(user)) {
-            log.info("鐧诲綍鐢ㄦ埛锛歿} 涓嶅瓨鍦�.", openid);
-            // todo 鐢ㄦ埛涓嶅瓨鍦� 涓氬姟閫昏緫鑷瀹炵幇
-        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
-            log.info("鐧诲綍鐢ㄦ埛锛歿} 宸茶鍋滅敤.", openid);
-            // todo 鐢ㄦ埛宸茶鍋滅敤 涓氬姟閫昏緫鑷瀹炵幇
-        }
-        return user;
-    }
-
-    /**
-     * 鏋勫缓鐧诲綍鐢ㄦ埛
-     */
-    private LoginUser buildLoginUser(SysUserVo user) {
-        LoginUser loginUser = new LoginUser();
-        loginUser.setTenantId(user.getTenantId());
-        loginUser.setUserId(user.getUserId());
-        loginUser.setDeptId(user.getDeptId());
-        loginUser.setUsername(user.getUserName());
-        loginUser.setUserType(user.getUserType());
-        loginUser.setMenuPermission(permissionService.getMenuPermission(user.getUserId()));
-        loginUser.setRolePermission(permissionService.getRolePermission(user.getUserId()));
-        loginUser.setDeptName(ObjectUtil.isNull(user.getDept()) ? "" : user.getDept().getDeptName());
-        List<RoleDTO> roles = BeanUtil.copyToList(user.getRoles(), RoleDTO.class);
-        loginUser.setRoles(roles);
-        return loginUser;
-    }
-
-    /**
-     * 璁板綍鐧诲綍淇℃伅
-     *
-     * @param userId 鐢ㄦ埛ID
-     */
-    public void recordLoginInfo(Long userId) {
-        SysUser sysUser = new SysUser();
-        sysUser.setUserId(userId);
-        sysUser.setLoginIp(ServletUtils.getClientIP());
-        sysUser.setLoginDate(DateUtils.getNowDate());
-        sysUser.setUpdateBy(userId);
-        userMapper.updateById(sysUser);
-    }
-
-    /**
-     * 鐧诲綍鏍¢獙
-     */
-    private void checkLogin(LoginType loginType, String tenantId, String username, Supplier<Boolean> supplier) {
-        String errorKey = GlobalConstants.PWD_ERR_CNT_KEY + username;
-        String loginFail = Constants.LOGIN_FAIL;
-
-        // 鑾峰彇鐢ㄦ埛鐧诲綍閿欒娆℃暟(鍙嚜瀹氫箟闄愬埗绛栫暐 渚嬪: key + username + ip)
-        Integer errorNumber = RedisUtils.getCacheObject(errorKey);
-        // 閿佸畾鏃堕棿鍐呯櫥褰� 鍒欒涪鍑�
-        if (ObjectUtil.isNotNull(errorNumber) && errorNumber.equals(maxRetryCount)) {
-            recordLogininfor(tenantId, username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), maxRetryCount, lockTime));
-            throw new UserException(loginType.getRetryLimitExceed(), maxRetryCount, lockTime);
-        }
-
-        if (supplier.get()) {
-            // 鏄惁绗竴娆�
-            errorNumber = ObjectUtil.isNull(errorNumber) ? 1 : errorNumber + 1;
-            // 杈惧埌瑙勫畾閿欒娆℃暟 鍒欓攣瀹氱櫥褰�
-            if (errorNumber.equals(maxRetryCount)) {
-                RedisUtils.setCacheObject(errorKey, errorNumber, Duration.ofMinutes(lockTime));
-                recordLogininfor(tenantId, username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), maxRetryCount, lockTime));
-                throw new UserException(loginType.getRetryLimitExceed(), maxRetryCount, lockTime);
-            } else {
-                // 鏈揪鍒拌瀹氶敊璇鏁� 鍒欓�掑
-                RedisUtils.setCacheObject(errorKey, errorNumber);
-                recordLogininfor(tenantId, username, loginFail, MessageUtils.message(loginType.getRetryLimitCount(), errorNumber));
-                throw new UserException(loginType.getRetryLimitCount(), errorNumber);
-            }
-        }
-
-        // 鐧诲綍鎴愬姛 娓呯┖閿欒娆℃暟
-        RedisUtils.deleteObject(errorKey);
-    }
-
-    private void checkTenant(String tenantId) {
-        if (!TenantHelper.isEnable()) {
-            return;
-        }
-        if (TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) {
-            return;
-        }
-        SysTenantVo tenant = tenantService.queryByTenantId(tenantId);
-        if (ObjectUtil.isNull(tenant)) {
-            log.info("鐧诲綍绉熸埛锛歿} 涓嶅瓨鍦�.", tenantId);
-            throw new TenantException("tenant.not.exists");
-        } else if (TenantStatus.DISABLE.getCode().equals(tenant.getStatus())) {
-            log.info("鐧诲綍绉熸埛锛歿} 宸茶鍋滅敤.", tenantId);
-            throw new TenantException("tenant.blocked");
-        } else if (ObjectUtil.isNotNull(tenant.getExpireTime())
-                && new Date().after(tenant.getExpireTime())) {
-            log.info("鐧诲綍绉熸埛锛歿} 宸茶秴杩囨湁鏁堟湡.", tenantId);
-            throw new TenantException("tenant.expired");
-        }
-    }
-
-}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/service/SysRegisterService.java b/ruoyi-admin/src/main/java/com/ruoyi/web/service/SysRegisterService.java
deleted file mode 100644
index 819c759..0000000
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/service/SysRegisterService.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package com.ruoyi.web.service;
-
-import cn.dev33.satoken.secure.BCrypt;
-import com.ruoyi.common.core.constant.Constants;
-import com.ruoyi.common.core.constant.GlobalConstants;
-import com.ruoyi.common.core.domain.model.RegisterBody;
-import com.ruoyi.common.core.enums.UserType;
-import com.ruoyi.common.core.exception.user.CaptchaException;
-import com.ruoyi.common.core.exception.user.CaptchaExpireException;
-import com.ruoyi.common.core.exception.user.UserException;
-import com.ruoyi.common.core.utils.MessageUtils;
-import com.ruoyi.common.core.utils.ServletUtils;
-import com.ruoyi.common.core.utils.SpringUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.log.event.LogininforEvent;
-import com.ruoyi.common.redis.utils.RedisUtils;
-import com.ruoyi.common.web.config.properties.CaptchaProperties;
-import com.ruoyi.system.domain.bo.SysUserBo;
-import com.ruoyi.system.service.ISysUserService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Service;
-
-/**
- * 娉ㄥ唽鏍¢獙鏂规硶
- *
- * @author Lion Li
- */
-@RequiredArgsConstructor
-@Service
-public class SysRegisterService {
-
-    private final ISysUserService userService;
-    private final CaptchaProperties captchaProperties;
-
-    /**
-     * 娉ㄥ唽
-     */
-    public void register(RegisterBody registerBody) {
-        String tenantId = registerBody.getTenantId();
-        String username = registerBody.getUsername();
-        String password = registerBody.getPassword();
-        // 鏍¢獙鐢ㄦ埛绫诲瀷鏄惁瀛樺湪
-        String userType = UserType.getUserType(registerBody.getUserType()).getUserType();
-
-        boolean captchaEnabled = captchaProperties.getEnable();
-        // 楠岃瘉鐮佸紑鍏�
-        if (captchaEnabled) {
-            validateCaptcha(tenantId, username, registerBody.getCode(), registerBody.getUuid());
-        }
-        SysUserBo sysUser = new SysUserBo();
-        sysUser.setUserName(username);
-        sysUser.setNickName(username);
-        sysUser.setPassword(BCrypt.hashpw(password));
-        sysUser.setUserType(userType);
-
-        if (!userService.checkUserNameUnique(sysUser)) {
-            throw new UserException("user.register.save.error", username);
-        }
-        boolean regFlag = userService.registerUser(sysUser, tenantId);
-        if (!regFlag) {
-            throw new UserException("user.register.error");
-        }
-        recordLogininfor(tenantId, username, Constants.REGISTER, MessageUtils.message("user.register.success"));
-    }
-
-    /**
-     * 鏍¢獙楠岃瘉鐮�
-     *
-     * @param username 鐢ㄦ埛鍚�
-     * @param code     楠岃瘉鐮�
-     * @param uuid     鍞竴鏍囪瘑
-     */
-    public void validateCaptcha(String tenantId, String username, String code, String uuid) {
-        String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
-        String captcha = RedisUtils.getCacheObject(verifyKey);
-        RedisUtils.deleteObject(verifyKey);
-        if (captcha == null) {
-            recordLogininfor(tenantId, username, Constants.REGISTER, MessageUtils.message("user.jcaptcha.expire"));
-            throw new CaptchaExpireException();
-        }
-        if (!code.equalsIgnoreCase(captcha)) {
-            recordLogininfor(tenantId, username, Constants.REGISTER, MessageUtils.message("user.jcaptcha.error"));
-            throw new CaptchaException();
-        }
-    }
-
-    /**
-     * 璁板綍鐧诲綍淇℃伅
-     *
-     * @param tenantId 绉熸埛ID
-     * @param username 鐢ㄦ埛鍚�
-     * @param status   鐘舵��
-     * @param message  娑堟伅鍐呭
-     * @return
-     */
-    private void recordLogininfor(String tenantId, String username, String status, String message) {
-        LogininforEvent logininforEvent = new LogininforEvent();
-        logininforEvent.setTenantId(tenantId);
-        logininforEvent.setUsername(username);
-        logininforEvent.setStatus(status);
-        logininforEvent.setMessage(message);
-        logininforEvent.setRequest(ServletUtils.getRequest());
-        SpringUtils.context().publishEvent(logininforEvent);
-    }
-
-}
diff --git a/ruoyi-admin/src/main/java/org/dromara/DromaraApplication.java b/ruoyi-admin/src/main/java/org/dromara/DromaraApplication.java
new file mode 100644
index 0000000..8ef33fe
--- /dev/null
+++ b/ruoyi-admin/src/main/java/org/dromara/DromaraApplication.java
@@ -0,0 +1,23 @@
+package org.dromara;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
+
+/**
+ * 鍚姩绋嬪簭
+ *
+ * @author Lion Li
+ */
+
+@SpringBootApplication
+public class DromaraApplication {
+
+    public static void main(String[] args) {
+        SpringApplication application = new SpringApplication(DromaraApplication.class);
+        application.setApplicationStartup(new BufferingApplicationStartup(2048));
+        application.run(args);
+        System.out.println("(鈾モ棤鈥库棤)锞夛緸  RuoYi-Vue-Plus鍚姩鎴愬姛   醿�(麓凇`醿�)锞�");
+    }
+
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/DromaraServletInitializer.java b/ruoyi-admin/src/main/java/org/dromara/DromaraServletInitializer.java
new file mode 100644
index 0000000..066a683
--- /dev/null
+++ b/ruoyi-admin/src/main/java/org/dromara/DromaraServletInitializer.java
@@ -0,0 +1,18 @@
+package org.dromara;
+
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+
+/**
+ * web瀹瑰櫒涓繘琛岄儴缃�
+ *
+ * @author Lion Li
+ */
+public class DromaraServletInitializer extends SpringBootServletInitializer {
+
+    @Override
+    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+        return application.sources(DromaraApplication.class);
+    }
+
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java b/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java
new file mode 100644
index 0000000..f39fd30
--- /dev/null
+++ b/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java
@@ -0,0 +1,153 @@
+package org.dromara.web.controller;
+
+import cn.dev33.satoken.annotation.SaIgnore;
+import cn.hutool.core.collection.CollUtil;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.domain.model.EmailLoginBody;
+import org.dromara.common.core.domain.model.LoginBody;
+import org.dromara.common.core.domain.model.RegisterBody;
+import org.dromara.common.core.domain.model.SmsLoginBody;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StreamUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.tenant.helper.TenantHelper;
+import org.dromara.system.domain.bo.SysTenantBo;
+import org.dromara.system.domain.vo.SysTenantVo;
+import org.dromara.system.service.ISysConfigService;
+import org.dromara.system.service.ISysTenantService;
+import org.dromara.web.domain.vo.LoginTenantVo;
+import org.dromara.web.domain.vo.LoginVo;
+import org.dromara.web.domain.vo.TenantListVo;
+import org.dromara.web.service.SysLoginService;
+import org.dromara.web.service.SysRegisterService;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.validation.constraints.NotBlank;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.net.URL;
+import java.util.List;
+
+/**
+ * 璁よ瘉
+ *
+ * @author Lion Li
+ */
+@SaIgnore
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/auth")
+public class AuthController {
+
+    private final SysLoginService loginService;
+    private final SysRegisterService registerService;
+    private final ISysConfigService configService;
+    private final ISysTenantService tenantService;
+
+    /**
+     * 鐧诲綍鏂规硶
+     *
+     * @param body 鐧诲綍淇℃伅
+     * @return 缁撴灉
+     */
+    @PostMapping("/login")
+    public R<LoginVo> login(@Validated @RequestBody LoginBody body) {
+        LoginVo loginVo = new LoginVo();
+        // 鐢熸垚浠ょ墝
+        String token = loginService.login(
+                body.getTenantId(),
+                body.getUsername(), body.getPassword(),
+                body.getCode(), body.getUuid());
+        loginVo.setToken(token);
+        return R.ok(loginVo);
+    }
+
+    /**
+     * 鐭俊鐧诲綍
+     *
+     * @param body 鐧诲綍淇℃伅
+     * @return 缁撴灉
+     */
+    @PostMapping("/smsLogin")
+    public R<LoginVo> smsLogin(@Validated @RequestBody SmsLoginBody body) {
+        LoginVo loginVo = new LoginVo();
+        // 鐢熸垚浠ょ墝
+        String token = loginService.smsLogin(body.getTenantId(), body.getPhonenumber(), body.getSmsCode());
+        loginVo.setToken(token);
+        return R.ok(loginVo);
+    }
+
+    /**
+     * 閭欢鐧诲綍
+     *
+     * @param body 鐧诲綍淇℃伅
+     * @return 缁撴灉
+     */
+    @PostMapping("/emailLogin")
+    public R<LoginVo> emailLogin(@Validated @RequestBody EmailLoginBody body) {
+        LoginVo loginVo = new LoginVo();
+        // 鐢熸垚浠ょ墝
+        String token = loginService.emailLogin(body.getTenantId(), body.getEmail(), body.getEmailCode());
+        loginVo.setToken(token);
+        return R.ok(loginVo);
+    }
+
+    /**
+     * 灏忕▼搴忕櫥褰�(绀轰緥)
+     *
+     * @param xcxCode 灏忕▼搴廲ode
+     * @return 缁撴灉
+     */
+    @PostMapping("/xcxLogin")
+    public R<LoginVo> xcxLogin(@NotBlank(message = "{xcx.code.not.blank}") String xcxCode) {
+        LoginVo loginVo = new LoginVo();
+        // 鐢熸垚浠ょ墝
+        String token = loginService.xcxLogin(xcxCode);
+        loginVo.setToken(token);
+        return R.ok(loginVo);
+    }
+
+    /**
+     * 閫�鍑虹櫥褰�
+     */
+    @PostMapping("/logout")
+    public R<Void> logout() {
+        loginService.logout();
+        return R.ok("閫�鍑烘垚鍔�");
+    }
+
+    /**
+     * 鐢ㄦ埛娉ㄥ唽
+     */
+    @PostMapping("/register")
+    public R<Void> register(@Validated @RequestBody RegisterBody user) {
+        if (!configService.selectRegisterEnabled(user.getTenantId())) {
+            return R.fail("褰撳墠绯荤粺娌℃湁寮�鍚敞鍐屽姛鑳斤紒");
+        }
+        registerService.register(user);
+        return R.ok();
+    }
+
+    /**
+     * 鐧诲綍椤甸潰绉熸埛涓嬫媺妗�
+     *
+     * @return 绉熸埛鍒楄〃
+     */
+    @GetMapping("/tenant/list")
+    public R<LoginTenantVo> tenantList(HttpServletRequest request) throws Exception {
+        List<SysTenantVo> tenantList = tenantService.queryList(new SysTenantBo());
+        List<TenantListVo> voList = MapstructUtils.convert(tenantList, TenantListVo.class);
+        // 鑾峰彇鍩熷悕
+        String host = new URL(request.getRequestURL().toString()).getHost();
+        // 鏍规嵁鍩熷悕杩涜绛涢��
+        List<TenantListVo> list = StreamUtils.filter(voList, vo -> StringUtils.equals(vo.getDomain(), host));
+        // 杩斿洖瀵硅薄
+        LoginTenantVo vo = new LoginTenantVo();
+        vo.setVoList(CollUtil.isNotEmpty(list) ? list : voList);
+        vo.setTenantEnabled(TenantHelper.isEnable());
+        return R.ok(vo);
+    }
+
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java b/ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java
new file mode 100644
index 0000000..e79880b
--- /dev/null
+++ b/ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java
@@ -0,0 +1,135 @@
+package org.dromara.web.controller;
+
+import cn.dev33.satoken.annotation.SaIgnore;
+import cn.hutool.captcha.AbstractCaptcha;
+import cn.hutool.captcha.generator.CodeGenerator;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.RandomUtil;
+import org.dromara.common.core.constant.Constants;
+import org.dromara.common.core.constant.GlobalConstants;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.core.utils.reflect.ReflectUtils;
+import org.dromara.common.mail.config.properties.MailProperties;
+import org.dromara.common.mail.utils.MailUtils;
+import org.dromara.common.redis.utils.RedisUtils;
+import org.dromara.common.sms.config.properties.SmsProperties;
+import org.dromara.common.sms.core.SmsTemplate;
+import org.dromara.common.sms.entity.SmsResult;
+import org.dromara.common.web.config.properties.CaptchaProperties;
+import org.dromara.common.web.enums.CaptchaType;
+import org.dromara.web.domain.vo.CaptchaVo;
+import jakarta.validation.constraints.NotBlank;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.expression.Expression;
+import org.springframework.expression.ExpressionParser;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.Duration;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 楠岃瘉鐮佹搷浣滃鐞�
+ *
+ * @author Lion Li
+ */
+@SaIgnore
+@Slf4j
+@Validated
+@RequiredArgsConstructor
+@RestController
+public class CaptchaController {
+
+    private final CaptchaProperties captchaProperties;
+    private final SmsProperties smsProperties;
+    private final MailProperties mailProperties;
+
+    /**
+     * 鐭俊楠岃瘉鐮�
+     *
+     * @param phonenumber 鐢ㄦ埛鎵嬫満鍙�
+     */
+    @GetMapping("/sms/code")
+    public R<Void> smsCode(@NotBlank(message = "{user.phonenumber.not.blank}") String phonenumber) {
+        if (!smsProperties.getEnabled()) {
+            return R.fail("褰撳墠绯荤粺娌℃湁寮�鍚煭淇″姛鑳斤紒");
+        }
+        String key = GlobalConstants.CAPTCHA_CODE_KEY + phonenumber;
+        String code = RandomUtil.randomNumbers(4);
+        RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
+        // 楠岃瘉鐮佹ā鏉縤d 鑷澶勭悊 (鏌ユ暟鎹簱鎴栧啓姝诲潎鍙�)
+        String templateId = "";
+        Map<String, String> map = new HashMap<>(1);
+        map.put("code", code);
+        SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class);
+        SmsResult result = smsTemplate.send(phonenumber, templateId, map);
+        if (!result.isSuccess()) {
+            log.error("楠岃瘉鐮佺煭淇″彂閫佸紓甯� => {}", result);
+            return R.fail(result.getMessage());
+        }
+        return R.ok();
+    }
+
+    /**
+     * 閭楠岃瘉鐮�
+     *
+     * @param email 閭
+     */
+    @GetMapping("/email/code")
+    public R<Void> emailCode(@NotBlank(message = "{user.email.not.blank}") String email) {
+        if (!mailProperties.getEnabled()) {
+            return R.fail("褰撳墠绯荤粺娌℃湁寮�鍚偖绠卞姛鑳斤紒");
+        }
+        String key = GlobalConstants.CAPTCHA_CODE_KEY + email;
+        String code = RandomUtil.randomNumbers(4);
+        RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
+        try {
+            MailUtils.sendText(email, "鐧诲綍楠岃瘉鐮�", "鎮ㄦ湰娆¢獙璇佺爜涓猴細" + code + "锛屾湁鏁堟�т负" + Constants.CAPTCHA_EXPIRATION + "鍒嗛挓锛岃灏藉揩濉啓銆�");
+        } catch (Exception e) {
+            log.error("楠岃瘉鐮佺煭淇″彂閫佸紓甯� => {}", e.getMessage());
+            return R.fail(e.getMessage());
+        }
+        return R.ok();
+    }
+
+    /**
+     * 鐢熸垚楠岃瘉鐮�
+     */
+    @GetMapping("/code")
+    public R<CaptchaVo> getCode() {
+        CaptchaVo captchaVo = new CaptchaVo();
+        boolean captchaEnabled = captchaProperties.getEnable();
+        if (!captchaEnabled) {
+            captchaVo.setCaptchaEnabled(false);
+            return R.ok(captchaVo);
+        }
+        // 淇濆瓨楠岃瘉鐮佷俊鎭�
+        String uuid = IdUtil.simpleUUID();
+        String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + uuid;
+        // 鐢熸垚楠岃瘉鐮�
+        CaptchaType captchaType = captchaProperties.getType();
+        boolean isMath = CaptchaType.MATH == captchaType;
+        Integer length = isMath ? captchaProperties.getNumberLength() : captchaProperties.getCharLength();
+        CodeGenerator codeGenerator = ReflectUtils.newInstance(captchaType.getClazz(), length);
+        AbstractCaptcha captcha = SpringUtils.getBean(captchaProperties.getCategory().getClazz());
+        captcha.setGenerator(codeGenerator);
+        captcha.createCode();
+        String code = captcha.getCode();
+        if (isMath) {
+            ExpressionParser parser = new SpelExpressionParser();
+            Expression exp = parser.parseExpression(StringUtils.remove(code, "="));
+            code = exp.getValue(String.class);
+        }
+        RedisUtils.setCacheObject(verifyKey, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
+        captchaVo.setUuid(uuid);
+        captchaVo.setImg(captcha.getImageBase64());
+        return R.ok(captchaVo);
+    }
+
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/controller/IndexController.java b/ruoyi-admin/src/main/java/org/dromara/web/controller/IndexController.java
new file mode 100644
index 0000000..c444f28
--- /dev/null
+++ b/ruoyi-admin/src/main/java/org/dromara/web/controller/IndexController.java
@@ -0,0 +1,32 @@
+package org.dromara.web.controller;
+
+import cn.dev33.satoken.annotation.SaIgnore;
+import org.dromara.common.core.config.RuoYiConfig;
+import org.dromara.common.core.utils.StringUtils;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 棣栭〉
+ *
+ * @author Lion Li
+ */
+@SaIgnore
+@RequiredArgsConstructor
+@RestController
+public class IndexController {
+
+    /**
+     * 绯荤粺鍩虹閰嶇疆
+     */
+    private final RuoYiConfig ruoyiConfig;
+
+    /**
+     * 璁块棶棣栭〉锛屾彁绀鸿
+     */
+    @GetMapping("/")
+    public String index() {
+        return StringUtils.format("娆㈣繋浣跨敤{}鍚庡彴绠$悊妗嗘灦锛屽綋鍓嶇増鏈細v{}锛岃閫氳繃鍓嶇鍦板潃璁块棶銆�", ruoyiConfig.getName(), ruoyiConfig.getVersion());
+    }
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/domain/vo/CaptchaVo.java b/ruoyi-admin/src/main/java/org/dromara/web/domain/vo/CaptchaVo.java
new file mode 100644
index 0000000..664df1e
--- /dev/null
+++ b/ruoyi-admin/src/main/java/org/dromara/web/domain/vo/CaptchaVo.java
@@ -0,0 +1,25 @@
+package org.dromara.web.domain.vo;
+
+import lombok.Data;
+
+/**
+ * 楠岃瘉鐮佷俊鎭�
+ *
+ * @author Michelle.Chung
+ */
+@Data
+public class CaptchaVo {
+
+    /**
+     * 鏄惁寮�鍚獙璇佺爜
+     */
+    private Boolean captchaEnabled = true;
+
+    private String uuid;
+
+    /**
+     * 楠岃瘉鐮佸浘鐗�
+     */
+    private String img;
+
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/domain/vo/LoginTenantVo.java b/ruoyi-admin/src/main/java/org/dromara/web/domain/vo/LoginTenantVo.java
new file mode 100644
index 0000000..0a83ace
--- /dev/null
+++ b/ruoyi-admin/src/main/java/org/dromara/web/domain/vo/LoginTenantVo.java
@@ -0,0 +1,25 @@
+package org.dromara.web.domain.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 鐧诲綍绉熸埛瀵硅薄
+ *
+ * @author Michelle.Chung
+ */
+@Data
+public class LoginTenantVo {
+
+    /**
+     * 绉熸埛寮�鍏�
+     */
+    private Boolean tenantEnabled;
+
+    /**
+     * 绉熸埛瀵硅薄鍒楄〃
+     */
+    private List<TenantListVo> voList;
+
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/domain/vo/LoginVo.java b/ruoyi-admin/src/main/java/org/dromara/web/domain/vo/LoginVo.java
new file mode 100644
index 0000000..ef5dac0
--- /dev/null
+++ b/ruoyi-admin/src/main/java/org/dromara/web/domain/vo/LoginVo.java
@@ -0,0 +1,15 @@
+package org.dromara.web.domain.vo;
+
+import lombok.Data;
+
+/**
+ * 鐧诲綍楠岃瘉淇℃伅
+ *
+ * @author Michelle.Chung
+ */
+@Data
+public class LoginVo {
+
+    private String token;
+
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/domain/vo/TenantListVo.java b/ruoyi-admin/src/main/java/org/dromara/web/domain/vo/TenantListVo.java
new file mode 100644
index 0000000..4d4bc89
--- /dev/null
+++ b/ruoyi-admin/src/main/java/org/dromara/web/domain/vo/TenantListVo.java
@@ -0,0 +1,22 @@
+package org.dromara.web.domain.vo;
+
+import org.dromara.system.domain.vo.SysTenantVo;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+/**
+ * 绉熸埛鍒楄〃
+ *
+ * @author Lion Li
+ */
+@Data
+@AutoMapper(target = SysTenantVo.class)
+public class TenantListVo {
+
+    private String tenantId;
+
+    private String companyName;
+
+    private String domain;
+
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java b/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java
new file mode 100644
index 0000000..5dd5770
--- /dev/null
+++ b/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java
@@ -0,0 +1,391 @@
+package org.dromara.web.service;
+
+import cn.dev33.satoken.exception.NotLoginException;
+import cn.dev33.satoken.secure.BCrypt;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import org.dromara.common.core.constant.Constants;
+import org.dromara.common.core.constant.GlobalConstants;
+import org.dromara.common.core.constant.TenantConstants;
+import org.dromara.common.core.domain.dto.RoleDTO;
+import org.dromara.common.core.domain.model.LoginUser;
+import org.dromara.common.core.domain.model.XcxLoginUser;
+import org.dromara.common.core.enums.DeviceType;
+import org.dromara.common.core.enums.LoginType;
+import org.dromara.common.core.enums.TenantStatus;
+import org.dromara.common.core.enums.UserStatus;
+import org.dromara.common.core.exception.user.CaptchaException;
+import org.dromara.common.core.exception.user.CaptchaExpireException;
+import org.dromara.common.core.exception.user.UserException;
+import org.dromara.common.core.utils.*;
+import org.dromara.common.log.event.LogininforEvent;
+import org.dromara.common.redis.utils.RedisUtils;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.common.tenant.exception.TenantException;
+import org.dromara.common.tenant.helper.TenantHelper;
+import org.dromara.common.web.config.properties.CaptchaProperties;
+import org.dromara.system.domain.SysUser;
+import org.dromara.system.domain.vo.SysTenantVo;
+import org.dromara.system.domain.vo.SysUserVo;
+import org.dromara.system.mapper.SysUserMapper;
+import org.dromara.system.service.ISysPermissionService;
+import org.dromara.system.service.ISysTenantService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.utils.*;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.time.Duration;
+import java.util.Date;
+import java.util.List;
+import java.util.function.Supplier;
+
+/**
+ * 鐧诲綍鏍¢獙鏂规硶
+ *
+ * @author Lion Li
+ */
+@RequiredArgsConstructor
+@Slf4j
+@Service
+public class SysLoginService {
+
+    private final SysUserMapper userMapper;
+    private final CaptchaProperties captchaProperties;
+    private final ISysPermissionService permissionService;
+    private final ISysTenantService tenantService;
+
+    @Value("${user.password.maxRetryCount}")
+    private Integer maxRetryCount;
+
+    @Value("${user.password.lockTime}")
+    private Integer lockTime;
+
+    /**
+     * 鐧诲綍楠岃瘉
+     *
+     * @param username 鐢ㄦ埛鍚�
+     * @param password 瀵嗙爜
+     * @param code     楠岃瘉鐮�
+     * @param uuid     鍞竴鏍囪瘑
+     * @return 缁撴灉
+     */
+    public String login(String tenantId, String username, String password, String code, String uuid) {
+        boolean captchaEnabled = captchaProperties.getEnable();
+        // 楠岃瘉鐮佸紑鍏�
+        if (captchaEnabled) {
+            validateCaptcha(tenantId, username, code, uuid);
+        }
+        // 鏍¢獙绉熸埛
+        checkTenant(tenantId);
+
+        SysUserVo user = loadUserByUsername(tenantId, username);
+        checkLogin(LoginType.PASSWORD, tenantId, username, () -> !BCrypt.checkpw(password, user.getPassword()));
+        // 姝ゅ鍙牴鎹櫥褰曠敤鎴风殑鏁版嵁涓嶅悓 鑷鍒涘缓 loginUser
+        LoginUser loginUser = buildLoginUser(user);
+        // 鐢熸垚token
+        LoginHelper.loginByDevice(loginUser, DeviceType.PC);
+
+        recordLogininfor(loginUser.getTenantId(), username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
+        recordLoginInfo(user.getUserId());
+        return StpUtil.getTokenValue();
+    }
+
+    public String smsLogin(String tenantId, String phonenumber, String smsCode) {
+        // 鏍¢獙绉熸埛
+        checkTenant(tenantId);
+        // 閫氳繃鎵嬫満鍙锋煡鎵剧敤鎴�
+        SysUserVo user = loadUserByPhonenumber(tenantId, phonenumber);
+
+        checkLogin(LoginType.SMS, tenantId, user.getUserName(), () -> !validateSmsCode(tenantId, phonenumber, smsCode));
+        // 姝ゅ鍙牴鎹櫥褰曠敤鎴风殑鏁版嵁涓嶅悓 鑷鍒涘缓 loginUser
+        LoginUser loginUser = buildLoginUser(user);
+        // 鐢熸垚token
+        LoginHelper.loginByDevice(loginUser, DeviceType.APP);
+
+        recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
+        recordLoginInfo(user.getUserId());
+        return StpUtil.getTokenValue();
+    }
+
+    public String emailLogin(String tenantId, String email, String emailCode) {
+        // 鏍¢獙绉熸埛
+        checkTenant(tenantId);
+        // 閫氳繃鎵嬫満鍙锋煡鎵剧敤鎴�
+        SysUserVo user = loadUserByEmail(tenantId, email);
+
+        checkLogin(LoginType.EMAIL, tenantId, user.getUserName(), () -> !validateEmailCode(tenantId, email, emailCode));
+        // 姝ゅ鍙牴鎹櫥褰曠敤鎴风殑鏁版嵁涓嶅悓 鑷鍒涘缓 loginUser
+        LoginUser loginUser = buildLoginUser(user);
+        // 鐢熸垚token
+        LoginHelper.loginByDevice(loginUser, DeviceType.APP);
+
+        recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
+        recordLoginInfo(user.getUserId());
+        return StpUtil.getTokenValue();
+    }
+
+
+    public String xcxLogin(String xcxCode) {
+        // xcxCode 涓� 灏忕▼搴忚皟鐢� wx.login 鎺堟潈鍚庤幏鍙�
+        // todo 浠ヤ笅鑷瀹炵幇
+        // 鏍¢獙 appid + appsrcret + xcxCode 璋冪敤鐧诲綍鍑瘉鏍¢獙鎺ュ彛 鑾峰彇 session_key 涓� openid
+        String openid = "";
+        SysUserVo user = loadUserByOpenid(openid);
+        // 鏍¢獙绉熸埛
+        checkTenant(user.getTenantId());
+
+        // 姝ゅ鍙牴鎹櫥褰曠敤鎴风殑鏁版嵁涓嶅悓 鑷鍒涘缓 loginUser
+        XcxLoginUser loginUser = new XcxLoginUser();
+        loginUser.setTenantId(user.getTenantId());
+        loginUser.setUserId(user.getUserId());
+        loginUser.setUsername(user.getUserName());
+        loginUser.setUserType(user.getUserType());
+        loginUser.setOpenid(openid);
+        // 鐢熸垚token
+        LoginHelper.loginByDevice(loginUser, DeviceType.XCX);
+
+        recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
+        recordLoginInfo(user.getUserId());
+        return StpUtil.getTokenValue();
+    }
+
+    /**
+     * 閫�鍑虹櫥褰�
+     */
+    public void logout() {
+        try {
+            LoginUser loginUser = LoginHelper.getLoginUser();
+            if (TenantHelper.isEnable() && LoginHelper.isSuperAdmin()) {
+                // 瓒呯骇绠$悊鍛� 鐧诲嚭娓呴櫎鍔ㄦ�佺鎴�
+                TenantHelper.clearDynamic();
+            }
+            StpUtil.logout();
+            recordLogininfor(loginUser.getTenantId(), loginUser.getUsername(), Constants.LOGOUT, MessageUtils.message("user.logout.success"));
+        } catch (NotLoginException ignored) {
+        }
+    }
+
+    /**
+     * 璁板綍鐧诲綍淇℃伅
+     *
+     * @param tenantId 绉熸埛ID
+     * @param username 鐢ㄦ埛鍚�
+     * @param status   鐘舵��
+     * @param message  娑堟伅鍐呭
+     */
+    private void recordLogininfor(String tenantId, String username, String status, String message) {
+        LogininforEvent logininforEvent = new LogininforEvent();
+        logininforEvent.setTenantId(tenantId);
+        logininforEvent.setUsername(username);
+        logininforEvent.setStatus(status);
+        logininforEvent.setMessage(message);
+        logininforEvent.setRequest(ServletUtils.getRequest());
+        SpringUtils.context().publishEvent(logininforEvent);
+    }
+
+    /**
+     * 鏍¢獙鐭俊楠岃瘉鐮�
+     */
+    private boolean validateSmsCode(String tenantId, String phonenumber, String smsCode) {
+        String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + phonenumber);
+        if (StringUtils.isBlank(code)) {
+            recordLogininfor(tenantId, phonenumber, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
+            throw new CaptchaExpireException();
+        }
+        return code.equals(smsCode);
+    }
+
+    /**
+     * 鏍¢獙閭楠岃瘉鐮�
+     */
+    private boolean validateEmailCode(String tenantId, String email, String emailCode) {
+        String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + email);
+        if (StringUtils.isBlank(code)) {
+            recordLogininfor(tenantId, email, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
+            throw new CaptchaExpireException();
+        }
+        return code.equals(emailCode);
+    }
+
+    /**
+     * 鏍¢獙楠岃瘉鐮�
+     *
+     * @param username 鐢ㄦ埛鍚�
+     * @param code     楠岃瘉鐮�
+     * @param uuid     鍞竴鏍囪瘑
+     */
+    public void validateCaptcha(String tenantId, String username, String code, String uuid) {
+        String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
+        String captcha = RedisUtils.getCacheObject(verifyKey);
+        RedisUtils.deleteObject(verifyKey);
+        if (captcha == null) {
+            recordLogininfor(tenantId, username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
+            throw new CaptchaExpireException();
+        }
+        if (!code.equalsIgnoreCase(captcha)) {
+            recordLogininfor(tenantId, username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"));
+            throw new CaptchaException();
+        }
+    }
+
+    private SysUserVo loadUserByUsername(String tenantId, String username) {
+        SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
+                .select(SysUser::getUserName, SysUser::getStatus)
+                .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId)
+                .eq(SysUser::getUserName, username));
+        if (ObjectUtil.isNull(user)) {
+            log.info("鐧诲綍鐢ㄦ埛锛歿} 涓嶅瓨鍦�.", username);
+            throw new UserException("user.not.exists", username);
+        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
+            log.info("鐧诲綍鐢ㄦ埛锛歿} 宸茶鍋滅敤.", username);
+            throw new UserException("user.blocked", username);
+        }
+        if (TenantHelper.isEnable()) {
+            return userMapper.selectTenantUserByUserName(username, tenantId);
+        }
+        return userMapper.selectUserByUserName(username);
+    }
+
+    private SysUserVo loadUserByPhonenumber(String tenantId, String phonenumber) {
+        SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
+                .select(SysUser::getPhonenumber, SysUser::getStatus)
+                .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId)
+                .eq(SysUser::getPhonenumber, phonenumber));
+        if (ObjectUtil.isNull(user)) {
+            log.info("鐧诲綍鐢ㄦ埛锛歿} 涓嶅瓨鍦�.", phonenumber);
+            throw new UserException("user.not.exists", phonenumber);
+        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
+            log.info("鐧诲綍鐢ㄦ埛锛歿} 宸茶鍋滅敤.", phonenumber);
+            throw new UserException("user.blocked", phonenumber);
+        }
+        if (TenantHelper.isEnable()) {
+            return userMapper.selectTenantUserByPhonenumber(phonenumber, tenantId);
+        }
+        return userMapper.selectUserByPhonenumber(phonenumber);
+    }
+
+    private SysUserVo loadUserByEmail(String tenantId, String email) {
+        SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
+            .select(SysUser::getPhonenumber, SysUser::getStatus)
+            .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId)
+            .eq(SysUser::getEmail, email));
+        if (ObjectUtil.isNull(user)) {
+            log.info("鐧诲綍鐢ㄦ埛锛歿} 涓嶅瓨鍦�.", email);
+            throw new UserException("user.not.exists", email);
+        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
+            log.info("鐧诲綍鐢ㄦ埛锛歿} 宸茶鍋滅敤.", email);
+            throw new UserException("user.blocked", email);
+        }
+        if (TenantHelper.isEnable()) {
+            return userMapper.selectTenantUserByEmail(email, tenantId);
+        }
+        return userMapper.selectUserByEmail(email);
+    }
+
+    private SysUserVo loadUserByOpenid(String openid) {
+        // 浣跨敤 openid 鏌ヨ缁戝畾鐢ㄦ埛 濡傛湭缁戝畾鐢ㄦ埛 鍒欐牴鎹笟鍔¤嚜琛屽鐞� 渚嬪 鍒涘缓榛樿鐢ㄦ埛
+        // todo 鑷瀹炵幇 userService.selectUserByOpenid(openid);
+        SysUserVo user = new SysUserVo();
+        if (ObjectUtil.isNull(user)) {
+            log.info("鐧诲綍鐢ㄦ埛锛歿} 涓嶅瓨鍦�.", openid);
+            // todo 鐢ㄦ埛涓嶅瓨鍦� 涓氬姟閫昏緫鑷瀹炵幇
+        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
+            log.info("鐧诲綍鐢ㄦ埛锛歿} 宸茶鍋滅敤.", openid);
+            // todo 鐢ㄦ埛宸茶鍋滅敤 涓氬姟閫昏緫鑷瀹炵幇
+        }
+        return user;
+    }
+
+    /**
+     * 鏋勫缓鐧诲綍鐢ㄦ埛
+     */
+    private LoginUser buildLoginUser(SysUserVo user) {
+        LoginUser loginUser = new LoginUser();
+        loginUser.setTenantId(user.getTenantId());
+        loginUser.setUserId(user.getUserId());
+        loginUser.setDeptId(user.getDeptId());
+        loginUser.setUsername(user.getUserName());
+        loginUser.setUserType(user.getUserType());
+        loginUser.setMenuPermission(permissionService.getMenuPermission(user.getUserId()));
+        loginUser.setRolePermission(permissionService.getRolePermission(user.getUserId()));
+        loginUser.setDeptName(ObjectUtil.isNull(user.getDept()) ? "" : user.getDept().getDeptName());
+        List<RoleDTO> roles = BeanUtil.copyToList(user.getRoles(), RoleDTO.class);
+        loginUser.setRoles(roles);
+        return loginUser;
+    }
+
+    /**
+     * 璁板綍鐧诲綍淇℃伅
+     *
+     * @param userId 鐢ㄦ埛ID
+     */
+    public void recordLoginInfo(Long userId) {
+        SysUser sysUser = new SysUser();
+        sysUser.setUserId(userId);
+        sysUser.setLoginIp(ServletUtils.getClientIP());
+        sysUser.setLoginDate(DateUtils.getNowDate());
+        sysUser.setUpdateBy(userId);
+        userMapper.updateById(sysUser);
+    }
+
+    /**
+     * 鐧诲綍鏍¢獙
+     */
+    private void checkLogin(LoginType loginType, String tenantId, String username, Supplier<Boolean> supplier) {
+        String errorKey = GlobalConstants.PWD_ERR_CNT_KEY + username;
+        String loginFail = Constants.LOGIN_FAIL;
+
+        // 鑾峰彇鐢ㄦ埛鐧诲綍閿欒娆℃暟(鍙嚜瀹氫箟闄愬埗绛栫暐 渚嬪: key + username + ip)
+        Integer errorNumber = RedisUtils.getCacheObject(errorKey);
+        // 閿佸畾鏃堕棿鍐呯櫥褰� 鍒欒涪鍑�
+        if (ObjectUtil.isNotNull(errorNumber) && errorNumber.equals(maxRetryCount)) {
+            recordLogininfor(tenantId, username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), maxRetryCount, lockTime));
+            throw new UserException(loginType.getRetryLimitExceed(), maxRetryCount, lockTime);
+        }
+
+        if (supplier.get()) {
+            // 鏄惁绗竴娆�
+            errorNumber = ObjectUtil.isNull(errorNumber) ? 1 : errorNumber + 1;
+            // 杈惧埌瑙勫畾閿欒娆℃暟 鍒欓攣瀹氱櫥褰�
+            if (errorNumber.equals(maxRetryCount)) {
+                RedisUtils.setCacheObject(errorKey, errorNumber, Duration.ofMinutes(lockTime));
+                recordLogininfor(tenantId, username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), maxRetryCount, lockTime));
+                throw new UserException(loginType.getRetryLimitExceed(), maxRetryCount, lockTime);
+            } else {
+                // 鏈揪鍒拌瀹氶敊璇鏁� 鍒欓�掑
+                RedisUtils.setCacheObject(errorKey, errorNumber);
+                recordLogininfor(tenantId, username, loginFail, MessageUtils.message(loginType.getRetryLimitCount(), errorNumber));
+                throw new UserException(loginType.getRetryLimitCount(), errorNumber);
+            }
+        }
+
+        // 鐧诲綍鎴愬姛 娓呯┖閿欒娆℃暟
+        RedisUtils.deleteObject(errorKey);
+    }
+
+    private void checkTenant(String tenantId) {
+        if (!TenantHelper.isEnable()) {
+            return;
+        }
+        if (TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) {
+            return;
+        }
+        SysTenantVo tenant = tenantService.queryByTenantId(tenantId);
+        if (ObjectUtil.isNull(tenant)) {
+            log.info("鐧诲綍绉熸埛锛歿} 涓嶅瓨鍦�.", tenantId);
+            throw new TenantException("tenant.not.exists");
+        } else if (TenantStatus.DISABLE.getCode().equals(tenant.getStatus())) {
+            log.info("鐧诲綍绉熸埛锛歿} 宸茶鍋滅敤.", tenantId);
+            throw new TenantException("tenant.blocked");
+        } else if (ObjectUtil.isNotNull(tenant.getExpireTime())
+                && new Date().after(tenant.getExpireTime())) {
+            log.info("鐧诲綍绉熸埛锛歿} 宸茶秴杩囨湁鏁堟湡.", tenantId);
+            throw new TenantException("tenant.expired");
+        }
+    }
+
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/SysRegisterService.java b/ruoyi-admin/src/main/java/org/dromara/web/service/SysRegisterService.java
new file mode 100644
index 0000000..013773e
--- /dev/null
+++ b/ruoyi-admin/src/main/java/org/dromara/web/service/SysRegisterService.java
@@ -0,0 +1,106 @@
+package org.dromara.web.service;
+
+import cn.dev33.satoken.secure.BCrypt;
+import org.dromara.common.core.constant.Constants;
+import org.dromara.common.core.constant.GlobalConstants;
+import org.dromara.common.core.domain.model.RegisterBody;
+import org.dromara.common.core.enums.UserType;
+import org.dromara.common.core.exception.user.CaptchaException;
+import org.dromara.common.core.exception.user.CaptchaExpireException;
+import org.dromara.common.core.exception.user.UserException;
+import org.dromara.common.core.utils.MessageUtils;
+import org.dromara.common.core.utils.ServletUtils;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.log.event.LogininforEvent;
+import org.dromara.common.redis.utils.RedisUtils;
+import org.dromara.common.web.config.properties.CaptchaProperties;
+import org.dromara.system.domain.bo.SysUserBo;
+import org.dromara.system.service.ISysUserService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+/**
+ * 娉ㄥ唽鏍¢獙鏂规硶
+ *
+ * @author Lion Li
+ */
+@RequiredArgsConstructor
+@Service
+public class SysRegisterService {
+
+    private final ISysUserService userService;
+    private final CaptchaProperties captchaProperties;
+
+    /**
+     * 娉ㄥ唽
+     */
+    public void register(RegisterBody registerBody) {
+        String tenantId = registerBody.getTenantId();
+        String username = registerBody.getUsername();
+        String password = registerBody.getPassword();
+        // 鏍¢獙鐢ㄦ埛绫诲瀷鏄惁瀛樺湪
+        String userType = UserType.getUserType(registerBody.getUserType()).getUserType();
+
+        boolean captchaEnabled = captchaProperties.getEnable();
+        // 楠岃瘉鐮佸紑鍏�
+        if (captchaEnabled) {
+            validateCaptcha(tenantId, username, registerBody.getCode(), registerBody.getUuid());
+        }
+        SysUserBo sysUser = new SysUserBo();
+        sysUser.setUserName(username);
+        sysUser.setNickName(username);
+        sysUser.setPassword(BCrypt.hashpw(password));
+        sysUser.setUserType(userType);
+
+        if (!userService.checkUserNameUnique(sysUser)) {
+            throw new UserException("user.register.save.error", username);
+        }
+        boolean regFlag = userService.registerUser(sysUser, tenantId);
+        if (!regFlag) {
+            throw new UserException("user.register.error");
+        }
+        recordLogininfor(tenantId, username, Constants.REGISTER, MessageUtils.message("user.register.success"));
+    }
+
+    /**
+     * 鏍¢獙楠岃瘉鐮�
+     *
+     * @param username 鐢ㄦ埛鍚�
+     * @param code     楠岃瘉鐮�
+     * @param uuid     鍞竴鏍囪瘑
+     */
+    public void validateCaptcha(String tenantId, String username, String code, String uuid) {
+        String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
+        String captcha = RedisUtils.getCacheObject(verifyKey);
+        RedisUtils.deleteObject(verifyKey);
+        if (captcha == null) {
+            recordLogininfor(tenantId, username, Constants.REGISTER, MessageUtils.message("user.jcaptcha.expire"));
+            throw new CaptchaExpireException();
+        }
+        if (!code.equalsIgnoreCase(captcha)) {
+            recordLogininfor(tenantId, username, Constants.REGISTER, MessageUtils.message("user.jcaptcha.error"));
+            throw new CaptchaException();
+        }
+    }
+
+    /**
+     * 璁板綍鐧诲綍淇℃伅
+     *
+     * @param tenantId 绉熸埛ID
+     * @param username 鐢ㄦ埛鍚�
+     * @param status   鐘舵��
+     * @param message  娑堟伅鍐呭
+     * @return
+     */
+    private void recordLogininfor(String tenantId, String username, String status, String message) {
+        LogininforEvent logininforEvent = new LogininforEvent();
+        logininforEvent.setTenantId(tenantId);
+        logininforEvent.setUsername(username);
+        logininforEvent.setStatus(status);
+        logininforEvent.setMessage(message);
+        logininforEvent.setRequest(ServletUtils.getRequest());
+        SpringUtils.context().publishEvent(logininforEvent);
+    }
+
+}
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index 758b264..bd307fb 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -5,7 +5,7 @@
   # 鐗堟湰
   version: ${revision}
   # 鐗堟潈骞翠唤
-  copyrightYear: 2022
+  copyrightYear: 2023
   # 瀹炰緥婕旂ず寮�鍏�
   demoEnabled: true
   # 鑾峰彇ip鍦板潃寮�鍏�
@@ -48,7 +48,7 @@
 # 鏃ュ織閰嶇疆
 logging:
   level:
-    com.ruoyi: @logging.level@
+    org.dromara: @logging.level@
     org.springframework: warn
   config: classpath:logback.xml
 
@@ -151,11 +151,11 @@
 mybatis-plus:
   # 涓嶆敮鎸佸鍖�, 濡傛湁闇�瑕佸彲鍦ㄦ敞瑙i厤缃� 鎴� 鎻愬崌鎵寘绛夌骇
   # 渚嬪 com.**.**.mapper
-  mapperPackage: com.ruoyi.**.mapper
+  mapperPackage: org.dromara.**.mapper
   # 瀵瑰簲鐨� XML 鏂囦欢浣嶇疆
   mapperLocations: classpath*:mapper/**/*Mapper.xml
   # 瀹炰綋鎵弿锛屽涓猵ackage鐢ㄩ�楀彿鎴栬�呭垎鍙峰垎闅�
-  typeAliasesPackage: com.ruoyi.**.domain
+  typeAliasesPackage: org.dromara.**.domain
   # 鍚姩鏃舵槸鍚︽鏌� MyBatis XML 鏂囦欢鐨勫瓨鍦紝榛樿涓嶆鏌�
   checkConfigLocation: false
   configuration:
@@ -212,7 +212,7 @@
     # 鎻忚堪
     description: '鎻忚堪锛氱敤浜庣鐞嗛泦鍥㈡棗涓嬪叕鍙哥殑浜哄憳淇℃伅,鍏蜂綋鍖呮嫭XXX,XXX妯″潡...'
     # 鐗堟湰
-    version: '鐗堟湰鍙�: ${ruoyi-vue-plus.version}'
+    version: '鐗堟湰鍙�: ${ruoyi.version}'
     # 浣滆�呬俊鎭�
     contact:
       name: Lion Li
@@ -236,13 +236,13 @@
   #杩欓噷瀹氫箟浜嗕袱涓垎缁勶紝鍙畾涔夊涓紝涔熷彲浠ヤ笉瀹氫箟
   group-configs:
     - group: 1.婕旂ず妯″潡
-      packages-to-scan: com.ruoyi.demo
+      packages-to-scan: org.dromara.demo
     - group: 2.閫氱敤妯″潡
-      packages-to-scan: com.ruoyi.web
+      packages-to-scan: org.dromara.web
     - group: 3.绯荤粺妯″潡
-      packages-to-scan: com.ruoyi.system
+      packages-to-scan: org.dromara.system
     - group: 4.浠g爜鐢熸垚妯″潡
-      packages-to-scan: com.ruoyi.generator
+      packages-to-scan: org.dromara.generator
 
 # 闃叉XSS鏀诲嚮
 xss:
diff --git a/ruoyi-admin/src/test/java/com/ruoyi/test/AssertUnitTest.java b/ruoyi-admin/src/test/java/com/ruoyi/test/AssertUnitTest.java
deleted file mode 100644
index 5b9c9f8..0000000
--- a/ruoyi-admin/src/test/java/com/ruoyi/test/AssertUnitTest.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.ruoyi.test;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-
-/**
- * 鏂█鍗曞厓娴嬭瘯妗堜緥
- *
- * @author Lion Li
- */
-@DisplayName("鏂█鍗曞厓娴嬭瘯妗堜緥")
-public class AssertUnitTest {
-
-    @DisplayName("娴嬭瘯 assertEquals 鏂规硶")
-    @Test
-    public void testAssertEquals() {
-        Assertions.assertEquals("666", new String("666"));
-        Assertions.assertNotEquals("666", new String("666"));
-    }
-
-    @DisplayName("娴嬭瘯 assertSame 鏂规硶")
-    @Test
-    public void testAssertSame() {
-        Object obj = new Object();
-        Object obj1 = obj;
-        Assertions.assertSame(obj, obj1);
-        Assertions.assertNotSame(obj, obj1);
-    }
-
-    @DisplayName("娴嬭瘯 assertTrue 鏂规硶")
-    @Test
-    public void testAssertTrue() {
-        Assertions.assertTrue(true);
-        Assertions.assertFalse(true);
-    }
-
-    @DisplayName("娴嬭瘯 assertNull 鏂规硶")
-    @Test
-    public void testAssertNull() {
-        Assertions.assertNull(null);
-        Assertions.assertNotNull(null);
-    }
-
-}
diff --git a/ruoyi-admin/src/test/java/com/ruoyi/test/DemoUnitTest.java b/ruoyi-admin/src/test/java/com/ruoyi/test/DemoUnitTest.java
deleted file mode 100644
index b40c123..0000000
--- a/ruoyi-admin/src/test/java/com/ruoyi/test/DemoUnitTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package com.ruoyi.test;
-
-import com.ruoyi.common.core.config.RuoYiConfig;
-import org.junit.jupiter.api.*;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * 鍗曞厓娴嬭瘯妗堜緥
- *
- * @author Lion Li
- */
-@SpringBootTest // 姝ゆ敞瑙e彧鑳藉湪 springboot 涓诲寘涓嬩娇鐢� 闇�鍖呭惈 main 鏂规硶涓� yml 閰嶇疆鏂囦欢
-@DisplayName("鍗曞厓娴嬭瘯妗堜緥")
-public class DemoUnitTest {
-
-    @Autowired
-    private RuoYiConfig ruoYiConfig;
-
-    @DisplayName("娴嬭瘯 @SpringBootTest @Test @DisplayName 娉ㄨВ")
-    @Test
-    public void testTest() {
-        System.out.println(ruoYiConfig);
-    }
-
-    @Disabled
-    @DisplayName("娴嬭瘯 @Disabled 娉ㄨВ")
-    @Test
-    public void testDisabled() {
-        System.out.println(ruoYiConfig);
-    }
-
-    @Timeout(value = 2L, unit = TimeUnit.SECONDS)
-    @DisplayName("娴嬭瘯 @Timeout 娉ㄨВ")
-    @Test
-    public void testTimeout() throws InterruptedException {
-        Thread.sleep(3000);
-        System.out.println(ruoYiConfig);
-    }
-
-
-    @DisplayName("娴嬭瘯 @RepeatedTest 娉ㄨВ")
-    @RepeatedTest(3)
-    public void testRepeatedTest() {
-        System.out.println(666);
-    }
-
-    @BeforeAll
-    public static void testBeforeAll() {
-        System.out.println("@BeforeAll ==================");
-    }
-
-    @BeforeEach
-    public void testBeforeEach() {
-        System.out.println("@BeforeEach ==================");
-    }
-
-    @AfterEach
-    public void testAfterEach() {
-        System.out.println("@AfterEach ==================");
-    }
-
-    @AfterAll
-    public static void testAfterAll() {
-        System.out.println("@AfterAll ==================");
-    }
-
-}
diff --git a/ruoyi-admin/src/test/java/com/ruoyi/test/ParamUnitTest.java b/ruoyi-admin/src/test/java/com/ruoyi/test/ParamUnitTest.java
deleted file mode 100644
index 9d61383..0000000
--- a/ruoyi-admin/src/test/java/com/ruoyi/test/ParamUnitTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package com.ruoyi.test;
-
-import com.ruoyi.common.core.enums.UserType;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.EnumSource;
-import org.junit.jupiter.params.provider.MethodSource;
-import org.junit.jupiter.params.provider.NullSource;
-import org.junit.jupiter.params.provider.ValueSource;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Stream;
-
-/**
- * 甯﹀弬鏁板崟鍏冩祴璇曟渚�
- *
- * @author Lion Li
- */
-@DisplayName("甯﹀弬鏁板崟鍏冩祴璇曟渚�")
-public class ParamUnitTest {
-
-    @DisplayName("娴嬭瘯 @ValueSource 娉ㄨВ")
-    @ParameterizedTest
-    @ValueSource(strings = {"t1", "t2", "t3"})
-    public void testValueSource(String str) {
-        System.out.println(str);
-    }
-
-    @DisplayName("娴嬭瘯 @NullSource 娉ㄨВ")
-    @ParameterizedTest
-    @NullSource
-    public void testNullSource(String str) {
-        System.out.println(str);
-    }
-
-    @DisplayName("娴嬭瘯 @EnumSource 娉ㄨВ")
-    @ParameterizedTest
-    @EnumSource(UserType.class)
-    public void testEnumSource(UserType type) {
-        System.out.println(type.getUserType());
-    }
-
-    @DisplayName("娴嬭瘯 @MethodSource 娉ㄨВ")
-    @ParameterizedTest
-    @MethodSource("getParam")
-    public void testMethodSource(String str) {
-        System.out.println(str);
-    }
-
-    public static Stream<String> getParam() {
-        List<String> list = new ArrayList<>();
-        list.add("t1");
-        list.add("t2");
-        list.add("t3");
-        return list.stream();
-    }
-
-    @BeforeEach
-    public void testBeforeEach() {
-        System.out.println("@BeforeEach ==================");
-    }
-
-    @AfterEach
-    public void testAfterEach() {
-        System.out.println("@AfterEach ==================");
-    }
-
-
-}
diff --git a/ruoyi-admin/src/test/java/com/ruoyi/test/TagUnitTest.java b/ruoyi-admin/src/test/java/com/ruoyi/test/TagUnitTest.java
deleted file mode 100644
index 04240a0..0000000
--- a/ruoyi-admin/src/test/java/com/ruoyi/test/TagUnitTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.ruoyi.test;
-
-import org.junit.jupiter.api.*;
-import org.springframework.boot.test.context.SpringBootTest;
-
-/**
- * 鏍囩鍗曞厓娴嬭瘯妗堜緥
- *
- * @author Lion Li
- */
-@SpringBootTest
-@DisplayName("鏍囩鍗曞厓娴嬭瘯妗堜緥")
-public class TagUnitTest {
-
-    @Tag("dev")
-    @DisplayName("娴嬭瘯 @Tag dev")
-    @Test
-    public void testTagDev() {
-        System.out.println("dev");
-    }
-
-    @Tag("prod")
-    @DisplayName("娴嬭瘯 @Tag prod")
-    @Test
-    public void testTagProd() {
-        System.out.println("prod");
-    }
-
-    @Tag("local")
-    @DisplayName("娴嬭瘯 @Tag local")
-    @Test
-    public void testTagLocal() {
-        System.out.println("local");
-    }
-
-    @Tag("exclude")
-    @DisplayName("娴嬭瘯 @Tag exclude")
-    @Test
-    public void testTagExclude() {
-        System.out.println("exclude");
-    }
-
-    @BeforeEach
-    public void testBeforeEach() {
-        System.out.println("@BeforeEach ==================");
-    }
-
-    @AfterEach
-    public void testAfterEach() {
-        System.out.println("@AfterEach ==================");
-    }
-
-
-}
diff --git a/ruoyi-admin/src/test/java/org/dromara/test/AssertUnitTest.java b/ruoyi-admin/src/test/java/org/dromara/test/AssertUnitTest.java
new file mode 100644
index 0000000..dba2323
--- /dev/null
+++ b/ruoyi-admin/src/test/java/org/dromara/test/AssertUnitTest.java
@@ -0,0 +1,45 @@
+package org.dromara.test;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+/**
+ * 鏂█鍗曞厓娴嬭瘯妗堜緥
+ *
+ * @author Lion Li
+ */
+@DisplayName("鏂█鍗曞厓娴嬭瘯妗堜緥")
+public class AssertUnitTest {
+
+    @DisplayName("娴嬭瘯 assertEquals 鏂规硶")
+    @Test
+    public void testAssertEquals() {
+        Assertions.assertEquals("666", new String("666"));
+        Assertions.assertNotEquals("666", new String("666"));
+    }
+
+    @DisplayName("娴嬭瘯 assertSame 鏂规硶")
+    @Test
+    public void testAssertSame() {
+        Object obj = new Object();
+        Object obj1 = obj;
+        Assertions.assertSame(obj, obj1);
+        Assertions.assertNotSame(obj, obj1);
+    }
+
+    @DisplayName("娴嬭瘯 assertTrue 鏂规硶")
+    @Test
+    public void testAssertTrue() {
+        Assertions.assertTrue(true);
+        Assertions.assertFalse(true);
+    }
+
+    @DisplayName("娴嬭瘯 assertNull 鏂规硶")
+    @Test
+    public void testAssertNull() {
+        Assertions.assertNull(null);
+        Assertions.assertNotNull(null);
+    }
+
+}
diff --git a/ruoyi-admin/src/test/java/org/dromara/test/DemoUnitTest.java b/ruoyi-admin/src/test/java/org/dromara/test/DemoUnitTest.java
new file mode 100644
index 0000000..5b3dfdc
--- /dev/null
+++ b/ruoyi-admin/src/test/java/org/dromara/test/DemoUnitTest.java
@@ -0,0 +1,70 @@
+package org.dromara.test;
+
+import org.dromara.common.core.config.RuoYiConfig;
+import org.junit.jupiter.api.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 鍗曞厓娴嬭瘯妗堜緥
+ *
+ * @author Lion Li
+ */
+@SpringBootTest // 姝ゆ敞瑙e彧鑳藉湪 springboot 涓诲寘涓嬩娇鐢� 闇�鍖呭惈 main 鏂规硶涓� yml 閰嶇疆鏂囦欢
+@DisplayName("鍗曞厓娴嬭瘯妗堜緥")
+public class DemoUnitTest {
+
+    @Autowired
+    private RuoYiConfig ruoYiConfig;
+
+    @DisplayName("娴嬭瘯 @SpringBootTest @Test @DisplayName 娉ㄨВ")
+    @Test
+    public void testTest() {
+        System.out.println(ruoYiConfig);
+    }
+
+    @Disabled
+    @DisplayName("娴嬭瘯 @Disabled 娉ㄨВ")
+    @Test
+    public void testDisabled() {
+        System.out.println(ruoYiConfig);
+    }
+
+    @Timeout(value = 2L, unit = TimeUnit.SECONDS)
+    @DisplayName("娴嬭瘯 @Timeout 娉ㄨВ")
+    @Test
+    public void testTimeout() throws InterruptedException {
+        Thread.sleep(3000);
+        System.out.println(ruoYiConfig);
+    }
+
+
+    @DisplayName("娴嬭瘯 @RepeatedTest 娉ㄨВ")
+    @RepeatedTest(3)
+    public void testRepeatedTest() {
+        System.out.println(666);
+    }
+
+    @BeforeAll
+    public static void testBeforeAll() {
+        System.out.println("@BeforeAll ==================");
+    }
+
+    @BeforeEach
+    public void testBeforeEach() {
+        System.out.println("@BeforeEach ==================");
+    }
+
+    @AfterEach
+    public void testAfterEach() {
+        System.out.println("@AfterEach ==================");
+    }
+
+    @AfterAll
+    public static void testAfterAll() {
+        System.out.println("@AfterAll ==================");
+    }
+
+}
diff --git a/ruoyi-admin/src/test/java/org/dromara/test/ParamUnitTest.java b/ruoyi-admin/src/test/java/org/dromara/test/ParamUnitTest.java
new file mode 100644
index 0000000..1db51df
--- /dev/null
+++ b/ruoyi-admin/src/test/java/org/dromara/test/ParamUnitTest.java
@@ -0,0 +1,72 @@
+package org.dromara.test;
+
+import org.dromara.common.core.enums.UserType;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.EnumSource;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.jupiter.params.provider.NullSource;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
+
+/**
+ * 甯﹀弬鏁板崟鍏冩祴璇曟渚�
+ *
+ * @author Lion Li
+ */
+@DisplayName("甯﹀弬鏁板崟鍏冩祴璇曟渚�")
+public class ParamUnitTest {
+
+    @DisplayName("娴嬭瘯 @ValueSource 娉ㄨВ")
+    @ParameterizedTest
+    @ValueSource(strings = {"t1", "t2", "t3"})
+    public void testValueSource(String str) {
+        System.out.println(str);
+    }
+
+    @DisplayName("娴嬭瘯 @NullSource 娉ㄨВ")
+    @ParameterizedTest
+    @NullSource
+    public void testNullSource(String str) {
+        System.out.println(str);
+    }
+
+    @DisplayName("娴嬭瘯 @EnumSource 娉ㄨВ")
+    @ParameterizedTest
+    @EnumSource(UserType.class)
+    public void testEnumSource(UserType type) {
+        System.out.println(type.getUserType());
+    }
+
+    @DisplayName("娴嬭瘯 @MethodSource 娉ㄨВ")
+    @ParameterizedTest
+    @MethodSource("getParam")
+    public void testMethodSource(String str) {
+        System.out.println(str);
+    }
+
+    public static Stream<String> getParam() {
+        List<String> list = new ArrayList<>();
+        list.add("t1");
+        list.add("t2");
+        list.add("t3");
+        return list.stream();
+    }
+
+    @BeforeEach
+    public void testBeforeEach() {
+        System.out.println("@BeforeEach ==================");
+    }
+
+    @AfterEach
+    public void testAfterEach() {
+        System.out.println("@AfterEach ==================");
+    }
+
+
+}
diff --git a/ruoyi-admin/src/test/java/org/dromara/test/TagUnitTest.java b/ruoyi-admin/src/test/java/org/dromara/test/TagUnitTest.java
new file mode 100644
index 0000000..b50afa6
--- /dev/null
+++ b/ruoyi-admin/src/test/java/org/dromara/test/TagUnitTest.java
@@ -0,0 +1,54 @@
+package org.dromara.test;
+
+import org.junit.jupiter.api.*;
+import org.springframework.boot.test.context.SpringBootTest;
+
+/**
+ * 鏍囩鍗曞厓娴嬭瘯妗堜緥
+ *
+ * @author Lion Li
+ */
+@SpringBootTest
+@DisplayName("鏍囩鍗曞厓娴嬭瘯妗堜緥")
+public class TagUnitTest {
+
+    @Tag("dev")
+    @DisplayName("娴嬭瘯 @Tag dev")
+    @Test
+    public void testTagDev() {
+        System.out.println("dev");
+    }
+
+    @Tag("prod")
+    @DisplayName("娴嬭瘯 @Tag prod")
+    @Test
+    public void testTagProd() {
+        System.out.println("prod");
+    }
+
+    @Tag("local")
+    @DisplayName("娴嬭瘯 @Tag local")
+    @Test
+    public void testTagLocal() {
+        System.out.println("local");
+    }
+
+    @Tag("exclude")
+    @DisplayName("娴嬭瘯 @Tag exclude")
+    @Test
+    public void testTagExclude() {
+        System.out.println("exclude");
+    }
+
+    @BeforeEach
+    public void testBeforeEach() {
+        System.out.println("@BeforeEach ==================");
+    }
+
+    @AfterEach
+    public void testAfterEach() {
+        System.out.println("@AfterEach ==================");
+    }
+
+
+}
diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml
index 83fcb99..3b6c113 100644
--- a/ruoyi-common/pom.xml
+++ b/ruoyi-common/pom.xml
@@ -4,7 +4,7 @@
          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>
+        <groupId>org.dromara</groupId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
diff --git a/ruoyi-common/ruoyi-common-bom/pom.xml b/ruoyi-common/ruoyi-common-bom/pom.xml
index f2a36f2..e3ee9c6 100644
--- a/ruoyi-common/ruoyi-common-bom/pom.xml
+++ b/ruoyi-common/ruoyi-common-bom/pom.xml
@@ -4,7 +4,7 @@
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
-    <groupId>com.ruoyi</groupId>
+    <groupId>org.dromara</groupId>
     <artifactId>ruoyi-common-bom</artifactId>
     <version>${revision}</version>
     <packaging>pom</packaging>
@@ -21,147 +21,147 @@
         <dependencies>
             <!-- 鏍稿績妯″潡 -->
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-common-core</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <!-- 鎺ュ彛妯″潡 -->
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-common-doc</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <!-- excel -->
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-common-excel</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <!-- 骞傜瓑 -->
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-common-idempotent</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <!-- 璋冨害妯″潡 -->
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-common-job</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <!-- 鏃ュ織璁板綍 -->
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-common-log</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <!-- 閭欢鏈嶅姟 -->
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-common-mail</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <!-- 鏁版嵁搴撴湇鍔� -->
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-common-mybatis</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <!-- OSS -->
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-common-oss</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <!-- 闄愭祦 -->
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-common-ratelimiter</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <!-- 缂撳瓨鏈嶅姟 -->
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-common-redis</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <!-- satoken -->
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-common-satoken</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <!-- 瀹夊叏妯″潡 -->
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-common-security</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <!-- 鐭俊妯″潡 -->
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-common-sms</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <!-- web鏈嶅姟 -->
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-common-web</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <!-- 缈昏瘧妯″潡 -->
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-common-translation</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <!-- 鑴辨晱妯″潡 -->
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-common-sensitive</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <!-- 搴忓垪鍖栨ā鍧� -->
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-common-json</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <!-- 鏁版嵁搴撳姞瑙e瘑妯″潡 -->
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-common-encrypt</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <!-- 绉熸埛妯″潡 -->
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-common-tenant</artifactId>
                 <version>${revision}</version>
             </dependency>
 
             <!-- WebSocket妯″潡 -->
             <dependency>
-                <groupId>com.ruoyi</groupId>
+                <groupId>org.dromara</groupId>
                 <artifactId>ruoyi-common-websocket</artifactId>
                 <version>${revision}</version>
             </dependency>
diff --git a/ruoyi-common/ruoyi-common-core/pom.xml b/ruoyi-common/ruoyi-common-core/pom.xml
index 601afd2..8871cc0 100644
--- a/ruoyi-common/ruoyi-common-core/pom.xml
+++ b/ruoyi-common/ruoyi-common-core/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-common</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/config/ApplicationConfig.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/config/ApplicationConfig.java
deleted file mode 100644
index ef741a0..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/config/ApplicationConfig.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.ruoyi.common.core.config;
-
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.context.annotation.EnableAspectJAutoProxy;
-
-/**
- * 绋嬪簭娉ㄨВ閰嶇疆
- *
- * @author Lion Li
- */
-@AutoConfiguration
-// 琛ㄧず閫氳繃aop妗嗘灦鏆撮湶璇ヤ唬鐞嗗璞�,AopContext鑳藉璁块棶
-@EnableAspectJAutoProxy(exposeProxy = true)
-public class ApplicationConfig {
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/config/AsyncConfig.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/config/AsyncConfig.java
deleted file mode 100644
index 5ed58f4..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/config/AsyncConfig.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.ruoyi.common.core.config;
-
-import cn.hutool.core.util.ArrayUtil;
-import com.ruoyi.common.core.exception.ServiceException;
-import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.scheduling.annotation.AsyncConfigurer;
-import org.springframework.scheduling.annotation.EnableAsync;
-
-import java.util.Arrays;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ScheduledExecutorService;
-
-/**
- * 寮傛閰嶇疆
- *
- * @author Lion Li
- */
-@EnableAsync(proxyTargetClass = true)
-@AutoConfiguration
-public class AsyncConfig implements AsyncConfigurer {
-
-    @Autowired
-    @Qualifier("scheduledExecutorService")
-    private ScheduledExecutorService scheduledExecutorService;
-
-    /**
-     * 鑷畾涔� @Async 娉ㄨВ浣跨敤绯荤粺绾跨▼姹�
-     */
-    @Override
-    public Executor getAsyncExecutor() {
-        return scheduledExecutorService;
-    }
-
-    /**
-     * 寮傛鎵ц寮傚父澶勭悊
-     */
-    @Override
-    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
-        return (throwable, method, objects) -> {
-            throwable.printStackTrace();
-            StringBuilder sb = new StringBuilder();
-            sb.append("Exception message - ").append(throwable.getMessage())
-                .append(", Method name - ").append(method.getName());
-            if (ArrayUtil.isNotEmpty(objects)) {
-                sb.append(", Parameter value - ").append(Arrays.toString(objects));
-            }
-            throw new ServiceException(sb.toString());
-        };
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/config/RuoYiConfig.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/config/RuoYiConfig.java
deleted file mode 100644
index e772a16..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/config/RuoYiConfig.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.ruoyi.common.core.config;
-
-import lombok.Data;
-import lombok.Getter;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.stereotype.Component;
-
-/**
- * 璇诲彇椤圭洰鐩稿叧閰嶇疆
- *
- * @author Lion Li
- */
-
-@Data
-@Component
-@ConfigurationProperties(prefix = "ruoyi")
-public class RuoYiConfig {
-
-    /**
-     * 椤圭洰鍚嶇О
-     */
-    private String name;
-
-    /**
-     * 鐗堟湰
-     */
-    private String version;
-
-    /**
-     * 鐗堟潈骞翠唤
-     */
-    private String copyrightYear;
-
-    /**
-     * 瀹炰緥婕旂ず寮�鍏�
-     */
-    private boolean demoEnabled;
-
-    /**
-     * 鑾峰彇鍦板潃寮�鍏�
-     */
-    @Getter
-    private static boolean addressEnabled;
-
-    public void setAddressEnabled(boolean addressEnabled) {
-        RuoYiConfig.addressEnabled = addressEnabled;
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/config/ThreadPoolConfig.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/config/ThreadPoolConfig.java
deleted file mode 100644
index ec09c64..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/config/ThreadPoolConfig.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package com.ruoyi.common.core.config;
-
-import com.ruoyi.common.core.config.properties.ThreadPoolProperties;
-import com.ruoyi.common.core.utils.Threads;
-import org.apache.commons.lang3.concurrent.BasicThreadFactory;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
-
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.ThreadPoolExecutor;
-
-/**
- * 绾跨▼姹犻厤缃�
- *
- * @author Lion Li
- **/
-@AutoConfiguration
-@EnableConfigurationProperties(ThreadPoolProperties.class)
-public class ThreadPoolConfig {
-
-    /**
-     * 鏍稿績绾跨▼鏁� = cpu 鏍稿績鏁� + 1
-     */
-    private final int core = Runtime.getRuntime().availableProcessors() + 1;
-
-    @Bean(name = "threadPoolTaskExecutor")
-    @ConditionalOnProperty(prefix = "thread-pool", name = "enabled", havingValue = "true")
-    public ThreadPoolTaskExecutor threadPoolTaskExecutor(ThreadPoolProperties threadPoolProperties) {
-        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
-        executor.setCorePoolSize(core);
-        executor.setMaxPoolSize(core * 2);
-        executor.setQueueCapacity(threadPoolProperties.getQueueCapacity());
-        executor.setKeepAliveSeconds(threadPoolProperties.getKeepAliveSeconds());
-        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
-        return executor;
-    }
-
-    /**
-     * 鎵ц鍛ㄦ湡鎬ф垨瀹氭椂浠诲姟
-     */
-    @Bean(name = "scheduledExecutorService")
-    protected ScheduledExecutorService scheduledExecutorService() {
-        return new ScheduledThreadPoolExecutor(core,
-            new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(),
-            new ThreadPoolExecutor.CallerRunsPolicy()) {
-            @Override
-            protected void afterExecute(Runnable r, Throwable t) {
-                super.afterExecute(r, t);
-                Threads.printException(r, t);
-            }
-        };
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/config/ValidatorConfig.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/config/ValidatorConfig.java
deleted file mode 100644
index 7c8fbe1..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/config/ValidatorConfig.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.ruoyi.common.core.config;
-
-import jakarta.validation.Validator;
-import org.hibernate.validator.HibernateValidator;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.context.MessageSource;
-import org.springframework.context.annotation.Bean;
-import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
-
-import java.util.Properties;
-
-/**
- * 鏍¢獙妗嗘灦閰嶇疆绫�
- *
- * @author Lion Li
- */
-@AutoConfiguration
-public class ValidatorConfig {
-
-    /**
-     * 閰嶇疆鏍¢獙妗嗘灦 蹇�熻繑鍥炴ā寮�
-     */
-    @Bean
-    public Validator validator(MessageSource messageSource) {
-        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-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/config/properties/ThreadPoolProperties.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/config/properties/ThreadPoolProperties.java
deleted file mode 100644
index d7f4678..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/config/properties/ThreadPoolProperties.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.ruoyi.common.core.config.properties;
-
-import lombok.Data;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-/**
- * 绾跨▼姹� 閰嶇疆灞炴��
- *
- * @author Lion Li
- */
-@Data
-@ConfigurationProperties(prefix = "thread-pool")
-public class ThreadPoolProperties {
-
-    /**
-     * 鏄惁寮�鍚嚎绋嬫睜
-     */
-    private boolean enabled;
-
-    /**
-     * 闃熷垪鏈�澶ч暱搴�
-     */
-    private int queueCapacity;
-
-    /**
-     * 绾跨▼姹犵淮鎶ょ嚎绋嬫墍鍏佽鐨勭┖闂叉椂闂�
-     */
-    private int keepAliveSeconds;
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheConstants.java
deleted file mode 100644
index c5e8707..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheConstants.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.ruoyi.common.core.constant;
-
-/**
- * 缂撳瓨鐨刱ey 甯搁噺
- *
- * @author Lion Li
- */
-public interface CacheConstants {
-
-    /**
-     * 鍦ㄧ嚎鐢ㄦ埛 redis key
-     */
-    String ONLINE_TOKEN_KEY = "online_tokens:";
-
-    /**
-     * 鍙傛暟绠$悊 cache key
-     */
-    String SYS_CONFIG_KEY = "sys_config:";
-
-    /**
-     * 瀛楀吀绠$悊 cache key
-     */
-    String SYS_DICT_KEY = "sys_dict:";
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheNames.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheNames.java
deleted file mode 100644
index 81e92f5..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheNames.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package com.ruoyi.common.core.constant;
-
-/**
- * 缂撳瓨缁勫悕绉板父閲�
- * <p>
- * key 鏍煎紡涓� cacheNames#ttl#maxIdleTime#maxSize
- * <p>
- * ttl 杩囨湡鏃堕棿 濡傛灉璁剧疆涓�0鍒欎笉杩囨湡 榛樿涓�0
- * maxIdleTime 鏈�澶х┖闂叉椂闂� 鏍规嵁LRU绠楁硶娓呯悊绌洪棽鏁版嵁 濡傛灉璁剧疆涓�0鍒欎笉妫�娴� 榛樿涓�0
- * maxSize 缁勬渶澶ч暱搴� 鏍规嵁LRU绠楁硶娓呯悊婧㈠嚭鏁版嵁 濡傛灉璁剧疆涓�0鍒欐棤闄愰暱 榛樿涓�0
- * <p>
- * 渚嬪瓙: test#60s銆乼est#0#60s銆乼est#0#1m#1000銆乼est#1h#0#500
- *
- * @author Lion Li
- */
-public interface CacheNames {
-
-    /**
-     * 婕旂ず妗堜緥
-     */
-    String DEMO_CACHE = "demo:cache#60s#10m#20";
-
-    /**
-     * 绯荤粺閰嶇疆
-     */
-    String SYS_CONFIG = "sys_config";
-
-    /**
-     * 鏁版嵁瀛楀吀
-     */
-    String SYS_DICT = "sys_dict";
-
-    /**
-     * 绉熸埛
-     */
-    String SYS_TENANT = GlobalConstants.GLOBAL_REDIS_KEY + "sys_tenant#30d";
-
-    /**
-     * 鐢ㄦ埛璐︽埛
-     */
-    String SYS_USER_NAME = "sys_user_name#30d";
-
-    /**
-     * 閮ㄩ棬
-     */
-    String SYS_DEPT = "sys_dept#30d";
-
-    /**
-     * OSS鍐呭
-     */
-    String SYS_OSS = "sys_oss#30d";
-
-    /**
-     * OSS閰嶇疆
-     */
-    String SYS_OSS_CONFIG = "sys_oss_config";
-
-    /**
-     * 鍦ㄧ嚎鐢ㄦ埛
-     */
-    String ONLINE_TOKEN = "online_tokens";
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java
deleted file mode 100644
index 9553d17..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package com.ruoyi.common.core.constant;
-
-/**
- * 閫氱敤甯搁噺淇℃伅
- *
- * @author ruoyi
- */
-public interface Constants {
-
-    /**
-     * UTF-8 瀛楃闆�
-     */
-    String UTF8 = "UTF-8";
-
-    /**
-     * GBK 瀛楃闆�
-     */
-    String GBK = "GBK";
-
-    /**
-     * www涓诲煙
-     */
-    String WWW = "www.";
-
-    /**
-     * http璇锋眰
-     */
-    String HTTP = "http://";
-
-    /**
-     * https璇锋眰
-     */
-    String HTTPS = "https://";
-
-    /**
-     * 閫氱敤鎴愬姛鏍囪瘑
-     */
-    String SUCCESS = "0";
-
-    /**
-     * 閫氱敤澶辫触鏍囪瘑
-     */
-    String FAIL = "1";
-
-    /**
-     * 鐧诲綍鎴愬姛
-     */
-    String LOGIN_SUCCESS = "Success";
-
-    /**
-     * 娉ㄩ攢
-     */
-    String LOGOUT = "Logout";
-
-    /**
-     * 娉ㄥ唽
-     */
-    String REGISTER = "Register";
-
-    /**
-     * 鐧诲綍澶辫触
-     */
-    String LOGIN_FAIL = "Error";
-
-    /**
-     * 楠岃瘉鐮佹湁鏁堟湡锛堝垎閽燂級
-     */
-    Integer CAPTCHA_EXPIRATION = 2;
-
-    /**
-     * 浠ょ墝
-     */
-    String TOKEN = "token";
-
-    /**
-     * 椤剁骇閮ㄩ棬id
-     */
-    Long TOP_PARENT_ID = 0L;
-
-}
-
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/GlobalConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/GlobalConstants.java
deleted file mode 100644
index 7fcdad1..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/GlobalConstants.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.ruoyi.common.core.constant;
-
-/**
- * 鍏ㄥ眬鐨刱ey甯搁噺 (涓氬姟鏃犲叧鐨刱ey)
- *
- * @author Lion Li
- */
-public interface GlobalConstants {
-
-    /**
-     * 鍏ㄥ眬 redis key (涓氬姟鏃犲叧鐨刱ey)
-     */
-    String GLOBAL_REDIS_KEY = "global:";
-
-    /**
-     * 鐧诲綍鐢ㄦ埛 redis key
-     */
-    String LOGIN_TOKEN_KEY = GLOBAL_REDIS_KEY + "Authorization:login:token:";
-
-    /**
-     * 楠岃瘉鐮� redis key
-     */
-    String CAPTCHA_CODE_KEY = GLOBAL_REDIS_KEY + "captcha_codes:";
-
-    /**
-     * 闃查噸鎻愪氦 redis key
-     */
-    String REPEAT_SUBMIT_KEY = GLOBAL_REDIS_KEY + "repeat_submit:";
-
-    /**
-     * 闄愭祦 redis key
-     */
-    String RATE_LIMIT_KEY = GLOBAL_REDIS_KEY + "rate_limit:";
-
-    /**
-     * 鐧诲綍璐︽埛瀵嗙爜閿欒娆℃暟 redis key
-     */
-    String PWD_ERR_CNT_KEY = GLOBAL_REDIS_KEY + "pwd_err_cnt:";
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/HttpStatus.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/HttpStatus.java
deleted file mode 100644
index d19931a..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/HttpStatus.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package com.ruoyi.common.core.constant;
-
-/**
- * 杩斿洖鐘舵�佺爜
- *
- * @author Lion Li
- */
-public interface HttpStatus {
-    /**
-     * 鎿嶄綔鎴愬姛
-     */
-    int SUCCESS = 200;
-
-    /**
-     * 瀵硅薄鍒涘缓鎴愬姛
-     */
-    int CREATED = 201;
-
-    /**
-     * 璇锋眰宸茬粡琚帴鍙�
-     */
-    int ACCEPTED = 202;
-
-    /**
-     * 鎿嶄綔宸茬粡鎵ц鎴愬姛锛屼絾鏄病鏈夎繑鍥炴暟鎹�
-     */
-    int NO_CONTENT = 204;
-
-    /**
-     * 璧勬簮宸茶绉婚櫎
-     */
-    int MOVED_PERM = 301;
-
-    /**
-     * 閲嶅畾鍚�
-     */
-    int SEE_OTHER = 303;
-
-    /**
-     * 璧勬簮娌℃湁琚慨鏀�
-     */
-    int NOT_MODIFIED = 304;
-
-    /**
-     * 鍙傛暟鍒楄〃閿欒锛堢己灏戯紝鏍煎紡涓嶅尮閰嶏級
-     */
-    int BAD_REQUEST = 400;
-
-    /**
-     * 鏈巿鏉�
-     */
-    int UNAUTHORIZED = 401;
-
-    /**
-     * 璁块棶鍙楅檺锛屾巿鏉冭繃鏈�
-     */
-    int FORBIDDEN = 403;
-
-    /**
-     * 璧勬簮锛屾湇鍔℃湭鎵惧埌
-     */
-    int NOT_FOUND = 404;
-
-    /**
-     * 涓嶅厑璁哥殑http鏂规硶
-     */
-    int BAD_METHOD = 405;
-
-    /**
-     * 璧勬簮鍐茬獊锛屾垨鑰呰祫婧愯閿�
-     */
-    int CONFLICT = 409;
-
-    /**
-     * 涓嶆敮鎸佺殑鏁版嵁锛屽獟浣撶被鍨�
-     */
-    int UNSUPPORTED_TYPE = 415;
-
-    /**
-     * 绯荤粺鍐呴儴閿欒
-     */
-    int ERROR = 500;
-
-    /**
-     * 鎺ュ彛鏈疄鐜�
-     */
-    int NOT_IMPLEMENTED = 501;
-
-    /**
-     * 绯荤粺璀﹀憡娑堟伅
-     */
-    int WARN = 601;
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TenantConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TenantConstants.java
deleted file mode 100644
index 6411ba4..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TenantConstants.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.ruoyi.common.core.constant;
-
-/**
- * 绉熸埛甯搁噺淇℃伅
- *
- * @author Lion Li
- */
-public interface TenantConstants {
-
-    /**
-     * 绉熸埛姝e父鐘舵��
-     */
-    String NORMAL = "0";
-
-    /**
-     * 绉熸埛灏佺鐘舵��
-     */
-    String DISABLE = "1";
-
-    /**
-     * 瓒呯骇绠$悊鍛業D
-     */
-    Long SUPER_ADMIN_ID = 1L;
-
-    /**
-     * 瓒呯骇绠$悊鍛樿鑹� roleKey
-     */
-    String SUPER_ADMIN_ROLE_KEY = "superadmin";
-
-    /**
-     * 绉熸埛绠$悊鍛樿鑹� roleKey
-     */
-    String TENANT_ADMIN_ROLE_KEY = "admin";
-
-    /**
-     * 绉熸埛绠$悊鍛樿鑹插悕绉�
-     */
-    String TENANT_ADMIN_ROLE_NAME = "绠$悊鍛�";
-
-    /**
-     * 榛樿绉熸埛ID
-     */
-    String DEFAULT_TENANT_ID = "000000";
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/UserConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/UserConstants.java
deleted file mode 100644
index 8539624..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/UserConstants.java
+++ /dev/null
@@ -1,132 +0,0 @@
-package com.ruoyi.common.core.constant;
-
-/**
- * 鐢ㄦ埛甯搁噺淇℃伅
- *
- * @author ruoyi
- */
-public interface UserConstants {
-
-    /**
-     * 骞冲彴鍐呯郴缁熺敤鎴风殑鍞竴鏍囧織
-     */
-    String SYS_USER = "SYS_USER";
-
-    /**
-     * 姝e父鐘舵��
-     */
-    String NORMAL = "0";
-
-    /**
-     * 寮傚父鐘舵��
-     */
-    String EXCEPTION = "1";
-
-    /**
-     * 鐢ㄦ埛姝e父鐘舵��
-     */
-    String USER_NORMAL = "0";
-
-    /**
-     * 鐢ㄦ埛灏佺鐘舵��
-     */
-    String USER_DISABLE = "1";
-
-    /**
-     * 瑙掕壊姝e父鐘舵��
-     */
-    String ROLE_NORMAL = "0";
-
-    /**
-     * 瑙掕壊灏佺鐘舵��
-     */
-    String ROLE_DISABLE = "1";
-
-    /**
-     * 閮ㄩ棬姝e父鐘舵��
-     */
-    String DEPT_NORMAL = "0";
-
-    /**
-     * 閮ㄩ棬鍋滅敤鐘舵��
-     */
-    String DEPT_DISABLE = "1";
-
-    /**
-     * 瀛楀吀姝e父鐘舵��
-     */
-    String DICT_NORMAL = "0";
-
-    /**
-     * 鏄惁涓虹郴缁熼粯璁わ紙鏄級
-     */
-    String YES = "Y";
-
-    /**
-     * 鏄惁鑿滃崟澶栭摼锛堟槸锛�
-     */
-    String YES_FRAME = "0";
-
-    /**
-     * 鏄惁鑿滃崟澶栭摼锛堝惁锛�
-     */
-    String NO_FRAME = "1";
-
-    /**
-     * 鑿滃崟姝e父鐘舵��
-     */
-    String MENU_NORMAL = "0";
-
-    /**
-     * 鑿滃崟鍋滅敤鐘舵��
-     */
-    String MENU_DISABLE = "1";
-
-    /**
-     * 鑿滃崟绫诲瀷锛堢洰褰曪級
-     */
-    String TYPE_DIR = "M";
-
-    /**
-     * 鑿滃崟绫诲瀷锛堣彍鍗曪級
-     */
-    String TYPE_MENU = "C";
-
-    /**
-     * 鑿滃崟绫诲瀷锛堟寜閽級
-     */
-    String TYPE_BUTTON = "F";
-
-    /**
-     * Layout缁勪欢鏍囪瘑
-     */
-    String LAYOUT = "Layout";
-
-    /**
-     * ParentView缁勪欢鏍囪瘑
-     */
-    String PARENT_VIEW = "ParentView";
-
-    /**
-     * InnerLink缁勪欢鏍囪瘑
-     */
-    String INNER_LINK = "InnerLink";
-
-    /**
-     * 鐢ㄦ埛鍚嶉暱搴﹂檺鍒�
-     */
-    int USERNAME_MIN_LENGTH = 2;
-    int USERNAME_MAX_LENGTH = 20;
-
-    /**
-     * 瀵嗙爜闀垮害闄愬埗
-     */
-    int PASSWORD_MIN_LENGTH = 5;
-    int PASSWORD_MAX_LENGTH = 20;
-
-    /**
-     * 瓒呯骇绠$悊鍛業D
-     */
-    Long SUPER_ADMIN_ID = 1L;
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/R.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/R.java
deleted file mode 100644
index 79b7941..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/R.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package com.ruoyi.common.core.domain;
-
-import com.ruoyi.common.core.constant.HttpStatus;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-/**
- * 鍝嶅簲淇℃伅涓讳綋
- *
- * @author Lion Li
- */
-@Data
-@NoArgsConstructor
-public class R<T> implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 鎴愬姛
-     */
-    public static final int SUCCESS = 200;
-
-    /**
-     * 澶辫触
-     */
-    public static final int FAIL = 500;
-
-    private int code;
-
-    private String msg;
-
-    private T data;
-
-    public static <T> R<T> ok() {
-        return restResult(null, SUCCESS, "鎿嶄綔鎴愬姛");
-    }
-
-    public static <T> R<T> ok(T data) {
-        return restResult(data, SUCCESS, "鎿嶄綔鎴愬姛");
-    }
-
-    public static <T> R<T> ok(String msg) {
-        return restResult(null, SUCCESS, msg);
-    }
-
-    public static <T> R<T> ok(String msg, T data) {
-        return restResult(data, SUCCESS, msg);
-    }
-
-    public static <T> R<T> fail() {
-        return restResult(null, FAIL, "鎿嶄綔澶辫触");
-    }
-
-    public static <T> R<T> fail(String msg) {
-        return restResult(null, FAIL, msg);
-    }
-
-    public static <T> R<T> fail(T data) {
-        return restResult(data, FAIL, "鎿嶄綔澶辫触");
-    }
-
-    public static <T> R<T> fail(String msg, T data) {
-        return restResult(data, FAIL, msg);
-    }
-
-    public static <T> R<T> fail(int code, String msg) {
-        return restResult(null, code, msg);
-    }
-
-    /**
-     * 杩斿洖璀﹀憡娑堟伅
-     *
-     * @param msg 杩斿洖鍐呭
-     * @return 璀﹀憡娑堟伅
-     */
-    public static <T> R<T> warn(String msg) {
-        return restResult(null, HttpStatus.WARN, msg);
-    }
-
-    /**
-     * 杩斿洖璀﹀憡娑堟伅
-     *
-     * @param msg 杩斿洖鍐呭
-     * @param data 鏁版嵁瀵硅薄
-     * @return 璀﹀憡娑堟伅
-     */
-    public static <T> R<T> warn(String msg, T data) {
-        return restResult(data, HttpStatus.WARN, msg);
-    }
-
-    private static <T> R<T> restResult(T data, int code, String msg) {
-        R<T> r = new R<>();
-        r.setCode(code);
-        r.setData(data);
-        r.setMsg(msg);
-        return r;
-    }
-
-    public static <T> Boolean isError(R<T> ret) {
-        return !isSuccess(ret);
-    }
-
-    public static <T> Boolean isSuccess(R<T> ret) {
-        return R.SUCCESS == ret.getCode();
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/dto/RoleDTO.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/dto/RoleDTO.java
deleted file mode 100644
index e25243f..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/dto/RoleDTO.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.ruoyi.common.core.domain.dto;
-
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.io.Serializable;
-
-/**
- * 瑙掕壊
- *
- * @author Lion Li
- */
-
-@Data
-@NoArgsConstructor
-public class RoleDTO implements Serializable {
-
-    /**
-     * 瑙掕壊ID
-     */
-    private Long roleId;
-
-    /**
-     * 瑙掕壊鍚嶇О
-     */
-    private String roleName;
-
-    /**
-     * 瑙掕壊鏉冮檺
-     */
-    private String roleKey;
-
-    /**
-     * 鏁版嵁鑼冨洿锛�1锛氭墍鏈夋暟鎹潈闄愶紱2锛氳嚜瀹氫箟鏁版嵁鏉冮檺锛�3锛氭湰閮ㄩ棬鏁版嵁鏉冮檺锛�4锛氭湰閮ㄩ棬鍙婁互涓嬫暟鎹潈闄愶紱5锛氫粎鏈汉鏁版嵁鏉冮檺锛�
-     */
-    private String dataScope;
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/dto/UserOnlineDTO.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/dto/UserOnlineDTO.java
deleted file mode 100644
index c8f568f..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/dto/UserOnlineDTO.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.ruoyi.common.core.domain.dto;
-
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-/**
- * 褰撳墠鍦ㄧ嚎浼氳瘽
- *
- * @author ruoyi
- */
-
-@Data
-@NoArgsConstructor
-public class UserOnlineDTO implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 浼氳瘽缂栧彿
-     */
-    private String tokenId;
-
-    /**
-     * 閮ㄩ棬鍚嶇О
-     */
-    private String deptName;
-
-    /**
-     * 鐢ㄦ埛鍚嶇О
-     */
-    private String userName;
-
-    /**
-     * 鐧诲綍IP鍦板潃
-     */
-    private String ipaddr;
-
-    /**
-     * 鐧诲綍鍦板潃
-     */
-    private String loginLocation;
-
-    /**
-     * 娴忚鍣ㄧ被鍨�
-     */
-    private String browser;
-
-    /**
-     * 鎿嶄綔绯荤粺
-     */
-    private String os;
-
-    /**
-     * 鐧诲綍鏃堕棿
-     */
-    private Long loginTime;
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/EmailLoginBody.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/EmailLoginBody.java
deleted file mode 100644
index 6459673..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/EmailLoginBody.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.ruoyi.common.core.domain.model;
-
-import jakarta.validation.constraints.Email;
-import jakarta.validation.constraints.NotBlank;
-import lombok.Data;
-
-/**
- * 鐭俊鐧诲綍瀵硅薄
- *
- * @author Lion Li
- */
-
-@Data
-public class EmailLoginBody {
-
-    /**
-     * 绉熸埛ID
-     */
-    @NotBlank(message = "{tenant.number.not.blank}")
-    private String tenantId;
-
-    /**
-     * 閭
-     */
-    @NotBlank(message = "{user.email.not.blank}")
-    @Email(message = "{user.email.not.valid}")
-    private String email;
-
-    /**
-     * 閭code
-     */
-    @NotBlank(message = "{email.code.not.blank}")
-    private String emailCode;
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java
deleted file mode 100644
index 153c02f..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.ruoyi.common.core.domain.model;
-
-import com.ruoyi.common.core.constant.UserConstants;
-import lombok.Data;
-import org.hibernate.validator.constraints.Length;
-
-import jakarta.validation.constraints.NotBlank;
-
-/**
- * 鐢ㄦ埛鐧诲綍瀵硅薄
- *
- * @author Lion Li
- */
-
-@Data
-public class LoginBody {
-
-    /**
-     * 绉熸埛ID
-     */
-    @NotBlank(message = "{tenant.number.not.blank}")
-    private String tenantId;
-
-    /**
-     * 鐢ㄦ埛鍚�
-     */
-    @NotBlank(message = "{user.username.not.blank}")
-    @Length(min = UserConstants.USERNAME_MIN_LENGTH, max = UserConstants.USERNAME_MAX_LENGTH, message = "{user.username.length.valid}")
-    private String username;
-
-    /**
-     * 鐢ㄦ埛瀵嗙爜
-     */
-    @NotBlank(message = "{user.password.not.blank}")
-    @Length(min = UserConstants.PASSWORD_MIN_LENGTH, max = UserConstants.PASSWORD_MAX_LENGTH, message = "{user.password.length.valid}")
-    private String password;
-
-    /**
-     * 楠岃瘉鐮�
-     */
-    private String code;
-
-    /**
-     * 鍞竴鏍囪瘑
-     */
-    private String uuid;
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java
deleted file mode 100644
index 47126f2..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java
+++ /dev/null
@@ -1,123 +0,0 @@
-package com.ruoyi.common.core.domain.model;
-
-import com.ruoyi.common.core.domain.dto.RoleDTO;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.List;
-import java.util.Set;
-
-/**
- * 鐧诲綍鐢ㄦ埛韬唤鏉冮檺
- *
- * @author Lion Li
- */
-
-@Data
-@NoArgsConstructor
-public class LoginUser implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 绉熸埛ID
-     */
-    private String tenantId;
-
-    /**
-     * 鐢ㄦ埛ID
-     */
-    private Long userId;
-
-    /**
-     * 閮ㄩ棬ID
-     */
-    private Long deptId;
-
-    /**
-     * 閮ㄩ棬鍚�
-     */
-    private String deptName;
-
-    /**
-     * 鐢ㄦ埛鍞竴鏍囪瘑
-     */
-    private String token;
-
-    /**
-     * 鐢ㄦ埛绫诲瀷
-     */
-    private String userType;
-
-    /**
-     * 鐧诲綍鏃堕棿
-     */
-    private Long loginTime;
-
-    /**
-     * 杩囨湡鏃堕棿
-     */
-    private Long expireTime;
-
-    /**
-     * 鐧诲綍IP鍦板潃
-     */
-    private String ipaddr;
-
-    /**
-     * 鐧诲綍鍦扮偣
-     */
-    private String loginLocation;
-
-    /**
-     * 娴忚鍣ㄧ被鍨�
-     */
-    private String browser;
-
-    /**
-     * 鎿嶄綔绯荤粺
-     */
-    private String os;
-
-    /**
-     * 鑿滃崟鏉冮檺
-     */
-    private Set<String> menuPermission;
-
-    /**
-     * 瑙掕壊鏉冮檺
-     */
-    private Set<String> rolePermission;
-
-    /**
-     * 鐢ㄦ埛鍚�
-     */
-    private String username;
-
-    /**
-     * 瑙掕壊瀵硅薄
-     */
-    private List<RoleDTO> roles;
-
-    /**
-     * 鏁版嵁鏉冮檺 褰撳墠瑙掕壊ID
-     */
-    private Long roleId;
-
-    /**
-     * 鑾峰彇鐧诲綍id
-     */
-    public String getLoginId() {
-        if (userType == null) {
-            throw new IllegalArgumentException("鐢ㄦ埛绫诲瀷涓嶈兘涓虹┖");
-        }
-        if (userId == null) {
-            throw new IllegalArgumentException("鐢ㄦ埛ID涓嶈兘涓虹┖");
-        }
-        return userType + ":" + userId;
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/RegisterBody.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/RegisterBody.java
deleted file mode 100644
index 88367e7..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/RegisterBody.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.ruoyi.common.core.domain.model;
-
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * 鐢ㄦ埛娉ㄥ唽瀵硅薄
- *
- * @author Lion Li
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-public class RegisterBody extends LoginBody {
-
-    private String userType;
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/SmsLoginBody.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/SmsLoginBody.java
deleted file mode 100644
index 70df20d..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/SmsLoginBody.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.ruoyi.common.core.domain.model;
-
-import lombok.Data;
-
-import jakarta.validation.constraints.NotBlank;
-
-/**
- * 鐭俊鐧诲綍瀵硅薄
- *
- * @author Lion Li
- */
-
-@Data
-public class SmsLoginBody {
-
-    /**
-     * 绉熸埛ID
-     */
-    @NotBlank(message = "{tenant.number.not.blank}")
-    private String tenantId;
-
-    /**
-     * 鎵嬫満鍙�
-     */
-    @NotBlank(message = "{user.phonenumber.not.blank}")
-    private String phonenumber;
-
-    /**
-     * 鐭俊code
-     */
-    @NotBlank(message = "{sms.code.not.blank}")
-    private String smsCode;
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/XcxLoginUser.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/XcxLoginUser.java
deleted file mode 100644
index 5ac449b..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/XcxLoginUser.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.ruoyi.common.core.domain.model;
-
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
-
-import java.io.Serial;
-
-/**
- * 灏忕▼搴忕櫥褰曠敤鎴疯韩浠芥潈闄�
- *
- * @author Lion Li
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@NoArgsConstructor
-public class XcxLoginUser extends LoginUser {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * openid
-     */
-    private String openid;
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/DeviceType.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/DeviceType.java
deleted file mode 100644
index b15b91c..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/DeviceType.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.ruoyi.common.core.enums;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 璁惧绫诲瀷
- * 閽堝涓�濂� 鐢ㄦ埛浣撶郴
- *
- * @author Lion Li
- */
-@Getter
-@AllArgsConstructor
-public enum DeviceType {
-
-    /**
-     * pc绔�
-     */
-    PC("pc"),
-
-    /**
-     * app绔�
-     */
-    APP("app"),
-
-    /**
-     * 灏忕▼搴忕
-     */
-    XCX("xcx");
-
-    private final String device;
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/LoginType.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/LoginType.java
deleted file mode 100644
index dbd6de1..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/LoginType.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package com.ruoyi.common.core.enums;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 鐧诲綍绫诲瀷
- *
- * @author Lion Li
- */
-@Getter
-@AllArgsConstructor
-public enum LoginType {
-
-    /**
-     * 瀵嗙爜鐧诲綍
-     */
-    PASSWORD("user.password.retry.limit.exceed", "user.password.retry.limit.count"),
-
-    /**
-     * 鐭俊鐧诲綍
-     */
-    SMS("sms.code.retry.limit.exceed", "sms.code.retry.limit.count"),
-
-    /**
-     * 閭鐧诲綍
-     */
-    EMAIL("email.code.retry.limit.exceed", "email.code.retry.limit.count"),
-
-    /**
-     * 灏忕▼搴忕櫥褰�
-     */
-    XCX("", "");
-
-    /**
-     * 鐧诲綍閲嶈瘯瓒呭嚭闄愬埗鎻愮ず
-     */
-    final String retryLimitExceed;
-
-    /**
-     * 鐧诲綍閲嶈瘯闄愬埗璁℃暟鎻愮ず
-     */
-    final String retryLimitCount;
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/TenantStatus.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/TenantStatus.java
deleted file mode 100644
index 166804b..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/TenantStatus.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.ruoyi.common.core.enums;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 鐢ㄦ埛鐘舵��
- *
- * @author LionLi
- */
-@Getter
-@AllArgsConstructor
-public enum TenantStatus {
-    /**
-     * 姝e父
-     */
-    OK("0", "姝e父"),
-    /**
-     * 鍋滅敤
-     */
-    DISABLE("1", "鍋滅敤"),
-    /**
-     * 鍒犻櫎
-     */
-    DELETED("2", "鍒犻櫎");
-
-    private final String code;
-    private final String info;
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/UserStatus.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/UserStatus.java
deleted file mode 100644
index 9d31518..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/UserStatus.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.ruoyi.common.core.enums;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 鐢ㄦ埛鐘舵��
- *
- * @author ruoyi
- */
-@Getter
-@AllArgsConstructor
-public enum UserStatus {
-    /**
-     * 姝e父
-     */
-    OK("0", "姝e父"),
-    /**
-     * 鍋滅敤
-     */
-    DISABLE("1", "鍋滅敤"),
-    /**
-     * 鍒犻櫎
-     */
-    DELETED("2", "鍒犻櫎");
-
-    private final String code;
-    private final String info;
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/UserType.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/UserType.java
deleted file mode 100644
index 46e4005..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/UserType.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.ruoyi.common.core.enums;
-
-import com.ruoyi.common.core.utils.StringUtils;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 璁惧绫诲瀷
- * 閽堝澶氬 鐢ㄦ埛浣撶郴
- *
- * @author Lion Li
- */
-@Getter
-@AllArgsConstructor
-public enum UserType {
-
-    /**
-     * pc绔�
-     */
-    SYS_USER("sys_user"),
-
-    /**
-     * app绔�
-     */
-    APP_USER("app_user");
-
-    private final String userType;
-
-    public static UserType getUserType(String str) {
-        for (UserType value : values()) {
-            if (StringUtils.contains(str, value.getUserType())) {
-                return value;
-            }
-        }
-        throw new RuntimeException("'UserType' not found By " + str);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/DemoModeException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/DemoModeException.java
deleted file mode 100644
index 7911e3c..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/DemoModeException.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.ruoyi.common.core.exception;
-
-import java.io.Serial;
-
-/**
- * 婕旂ず妯″紡寮傚父
- *
- * @author ruoyi
- */
-public class DemoModeException extends RuntimeException {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    public DemoModeException() {
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/GlobalException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/GlobalException.java
deleted file mode 100644
index 464d983..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/GlobalException.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package com.ruoyi.common.core.exception;
-
-import java.io.Serial;
-
-/**
- * 鍏ㄥ眬寮傚父
- *
- * @author ruoyi
- */
-public class GlobalException extends RuntimeException {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 閿欒鎻愮ず
-     */
-    private String message;
-
-    /**
-     * 閿欒鏄庣粏锛屽唴閮ㄨ皟璇曢敊璇�
-     */
-    private String detailMessage;
-
-    /**
-     * 绌烘瀯閫犳柟娉曪紝閬垮厤鍙嶅簭鍒楀寲闂
-     */
-    public GlobalException() {
-    }
-
-    public GlobalException(String message) {
-        this.message = message;
-    }
-
-    public String getDetailMessage() {
-        return detailMessage;
-    }
-
-    public GlobalException setDetailMessage(String detailMessage) {
-        this.detailMessage = detailMessage;
-        return this;
-    }
-
-    @Override
-    public String getMessage() {
-        return message;
-    }
-
-    public GlobalException setMessage(String message) {
-        this.message = message;
-        return this;
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/ServiceException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/ServiceException.java
deleted file mode 100644
index 0ef0534..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/ServiceException.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.ruoyi.common.core.exception;
-
-import java.io.Serial;
-
-/**
- * 涓氬姟寮傚父
- *
- * @author ruoyi
- */
-public final class ServiceException extends RuntimeException {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 閿欒鐮�
-     */
-    private Integer code;
-
-    /**
-     * 閿欒鎻愮ず
-     */
-    private String message;
-
-    /**
-     * 閿欒鏄庣粏锛屽唴閮ㄨ皟璇曢敊璇�
-     */
-    private String detailMessage;
-
-    /**
-     * 绌烘瀯閫犳柟娉曪紝閬垮厤鍙嶅簭鍒楀寲闂
-     */
-    public ServiceException() {
-    }
-
-    public ServiceException(String message) {
-        this.message = message;
-    }
-
-    public ServiceException(String message, Integer code) {
-        this.message = message;
-        this.code = code;
-    }
-
-    public String getDetailMessage() {
-        return detailMessage;
-    }
-
-    @Override
-    public String getMessage() {
-        return message;
-    }
-
-    public Integer getCode() {
-        return code;
-    }
-
-    public ServiceException setMessage(String message) {
-        this.message = message;
-        return this;
-    }
-
-    public ServiceException setDetailMessage(String detailMessage) {
-        this.detailMessage = detailMessage;
-        return this;
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/UtilException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/UtilException.java
deleted file mode 100644
index 587ae7f..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/UtilException.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.ruoyi.common.core.exception;
-
-import java.io.Serial;
-
-/**
- * 宸ュ叿绫诲紓甯�
- *
- * @author ruoyi
- */
-public class UtilException extends RuntimeException {
-
-    @Serial
-    private static final long serialVersionUID = 8247610319171014183L;
-
-    public UtilException(Throwable e) {
-        super(e.getMessage(), e);
-    }
-
-    public UtilException(String message) {
-        super(message);
-    }
-
-    public UtilException(String message, Throwable throwable) {
-        super(message, throwable);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/base/BaseException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/base/BaseException.java
deleted file mode 100644
index 195e141..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/base/BaseException.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package com.ruoyi.common.core.exception.base;
-
-import com.ruoyi.common.core.utils.MessageUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
-
-import java.io.Serial;
-
-/**
- * 鍩虹寮傚父
- *
- * @author ruoyi
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@NoArgsConstructor
-public class BaseException extends RuntimeException {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 鎵�灞炴ā鍧�
-     */
-    private String module;
-
-    /**
-     * 閿欒鐮�
-     */
-    private String code;
-
-    /**
-     * 閿欒鐮佸搴旂殑鍙傛暟
-     */
-    private Object[] args;
-
-    /**
-     * 閿欒娑堟伅
-     */
-    private String defaultMessage;
-
-    public BaseException(String module, String code, Object[] args, String defaultMessage) {
-        this.module = module;
-        this.code = code;
-        this.args = args;
-        this.defaultMessage = defaultMessage;
-    }
-
-    public BaseException(String module, String code, Object[] args) {
-        this(module, code, args, null);
-    }
-
-    public BaseException(String module, String defaultMessage) {
-        this(module, null, null, defaultMessage);
-    }
-
-    public BaseException(String code, Object[] args) {
-        this(null, code, args, null);
-    }
-
-    public BaseException(String defaultMessage) {
-        this(null, null, null, defaultMessage);
-    }
-
-    @Override
-    public String getMessage() {
-        String message = null;
-        if (!StringUtils.isEmpty(code)) {
-            message = MessageUtils.message(code, args);
-        }
-        if (message == null) {
-            message = defaultMessage;
-        }
-        return message;
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileException.java
deleted file mode 100644
index 8ee9e90..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileException.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.ruoyi.common.core.exception.file;
-
-import com.ruoyi.common.core.exception.base.BaseException;
-
-import java.io.Serial;
-
-/**
- * 鏂囦欢淇℃伅寮傚父绫�
- *
- * @author ruoyi
- */
-public class FileException extends BaseException {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    public FileException(String code, Object[] args) {
-        super("file", code, args, null);
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileNameLengthLimitExceededException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileNameLengthLimitExceededException.java
deleted file mode 100644
index 6d70b65..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileNameLengthLimitExceededException.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.ruoyi.common.core.exception.file;
-
-import java.io.Serial;
-
-/**
- * 鏂囦欢鍚嶇О瓒呴暱闄愬埗寮傚父绫�
- *
- * @author ruoyi
- */
-public class FileNameLengthLimitExceededException extends FileException {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    public FileNameLengthLimitExceededException(int defaultFileNameLength) {
-        super("upload.filename.exceed.length", new Object[]{defaultFileNameLength});
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileSizeLimitExceededException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileSizeLimitExceededException.java
deleted file mode 100644
index 940ae59..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileSizeLimitExceededException.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.ruoyi.common.core.exception.file;
-
-import java.io.Serial;
-
-/**
- * 鏂囦欢鍚嶅ぇ灏忛檺鍒跺紓甯哥被
- *
- * @author ruoyi
- */
-public class FileSizeLimitExceededException extends FileException {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    public FileSizeLimitExceededException(long defaultMaxSize) {
-        super("upload.exceed.maxSize", new Object[]{defaultMaxSize});
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/CaptchaException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/CaptchaException.java
deleted file mode 100644
index 700a501..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/CaptchaException.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.ruoyi.common.core.exception.user;
-
-import java.io.Serial;
-
-/**
- * 楠岃瘉鐮侀敊璇紓甯哥被
- *
- * @author ruoyi
- */
-public class CaptchaException extends UserException {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    public CaptchaException() {
-        super("user.jcaptcha.error");
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/CaptchaExpireException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/CaptchaExpireException.java
deleted file mode 100644
index 9cffe64..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/CaptchaExpireException.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.ruoyi.common.core.exception.user;
-
-import java.io.Serial;
-
-/**
- * 楠岃瘉鐮佸け鏁堝紓甯哥被
- *
- * @author ruoyi
- */
-public class CaptchaExpireException extends UserException {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    public CaptchaExpireException() {
-        super("user.jcaptcha.expire");
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/UserException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/UserException.java
deleted file mode 100644
index 4a9425c..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/UserException.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.ruoyi.common.core.exception.user;
-
-import com.ruoyi.common.core.exception.base.BaseException;
-
-import java.io.Serial;
-
-/**
- * 鐢ㄦ埛淇℃伅寮傚父绫�
- *
- * @author ruoyi
- */
-public class UserException extends BaseException {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    public UserException(String code, Object... args) {
-        super("user", code, args, null);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/UserPasswordNotMatchException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/UserPasswordNotMatchException.java
deleted file mode 100644
index 561b0cf..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/UserPasswordNotMatchException.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.ruoyi.common.core.exception.user;
-
-import java.io.Serial;
-
-/**
- * 鐢ㄦ埛瀵嗙爜涓嶆纭垨涓嶇鍚堣鑼冨紓甯哥被
- *
- * @author ruoyi
- */
-public class UserPasswordNotMatchException extends UserException {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    public UserPasswordNotMatchException() {
-        super("user.password.not.match");
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/UserPasswordRetryLimitExceedException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/UserPasswordRetryLimitExceedException.java
deleted file mode 100644
index 41719a1..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/UserPasswordRetryLimitExceedException.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.ruoyi.common.core.exception.user;
-
-import java.io.Serial;
-
-/**
- * 鐢ㄦ埛閿欒鏈�澶ф鏁板紓甯哥被
- *
- * @author ruoyi
- */
-public class UserPasswordRetryLimitExceedException extends UserException {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    public UserPasswordRetryLimitExceedException(int retryLimitCount, int lockTime) {
-        super("user.password.retry.limit.exceed", retryLimitCount, lockTime);
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/manager/ShutdownManager.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/manager/ShutdownManager.java
deleted file mode 100644
index ba1629b..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/manager/ShutdownManager.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.ruoyi.common.core.manager;
-
-import com.ruoyi.common.core.utils.Threads;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.stereotype.Component;
-
-import jakarta.annotation.PreDestroy;
-import java.util.concurrent.ScheduledExecutorService;
-
-/**
- * 纭繚搴旂敤閫�鍑烘椂鑳藉叧闂悗鍙扮嚎绋�
- *
- * @author Lion Li
- */
-@Slf4j
-@Component
-public class ShutdownManager {
-
-    @Autowired
-    @Qualifier("scheduledExecutorService")
-    private ScheduledExecutorService scheduledExecutorService;
-
-    @PreDestroy
-    public void destroy() {
-        shutdownAsyncManager();
-    }
-
-    /**
-     * 鍋滄寮傛鎵ц浠诲姟
-     */
-    private void shutdownAsyncManager() {
-        try {
-            log.info("====鍏抽棴鍚庡彴浠诲姟浠诲姟绾跨▼姹�====");
-            Threads.shutdownAndAwaitTermination(scheduledExecutorService);
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-        }
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/service/ConfigService.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/service/ConfigService.java
deleted file mode 100644
index c6badf6..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/service/ConfigService.java
+++ /dev/null
@@ -1,18 +0,0 @@
-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/ruoyi-common-core/src/main/java/com/ruoyi/common/core/service/DeptService.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/service/DeptService.java
deleted file mode 100644
index c27f461..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/service/DeptService.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.ruoyi.common.core.service;
-
-/**
- * 閫氱敤 閮ㄩ棬鏈嶅姟
- *
- * @author Lion Li
- */
-public interface DeptService {
-
-    /**
-     * 閫氳繃閮ㄩ棬ID鏌ヨ閮ㄩ棬鍚嶇О
-     *
-     * @param deptIds 閮ㄩ棬ID涓查�楀彿鍒嗛殧
-     * @return 閮ㄩ棬鍚嶇О涓查�楀彿鍒嗛殧
-     */
-    String selectDeptNameByIds(String deptIds);
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/service/DictService.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/service/DictService.java
deleted file mode 100644
index b334c82..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/service/DictService.java
+++ /dev/null
@@ -1,57 +0,0 @@
-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/ruoyi-common-core/src/main/java/com/ruoyi/common/core/service/OssService.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/service/OssService.java
deleted file mode 100644
index 65dda7c..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/service/OssService.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.ruoyi.common.core.service;
-
-/**
- * 閫氱敤 OSS鏈嶅姟
- *
- * @author Lion Li
- */
-public interface OssService {
-
-    /**
-     * 閫氳繃ossId鏌ヨ瀵瑰簲鐨剈rl
-     *
-     * @param ossIds ossId涓查�楀彿鍒嗛殧
-     * @return url涓查�楀彿鍒嗛殧
-     */
-    String selectUrlByIds(String ossIds);
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/service/UserService.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/service/UserService.java
deleted file mode 100644
index d2206c8..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/service/UserService.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.ruoyi.common.core.service;
-
-/**
- * 閫氱敤 鐢ㄦ埛鏈嶅姟
- *
- * @author Lion Li
- */
-public interface UserService {
-
-    /**
-     * 閫氳繃鐢ㄦ埛ID鏌ヨ鐢ㄦ埛璐︽埛
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 鐢ㄦ埛璐︽埛
-     */
-    String selectUserNameById(Long userId);
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/DateUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/DateUtils.java
deleted file mode 100644
index 804f1a2..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/DateUtils.java
+++ /dev/null
@@ -1,168 +0,0 @@
-package com.ruoyi.common.core.utils;
-
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import org.apache.commons.lang3.time.DateFormatUtils;
-
-import java.lang.management.ManagementFactory;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-import java.util.Date;
-
-/**
- * 鏃堕棿宸ュ叿绫�
- *
- * @author ruoyi
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
-
-    public static final String YYYY = "yyyy";
-
-    public static final String YYYY_MM = "yyyy-MM";
-
-    public static final String YYYY_MM_DD = "yyyy-MM-dd";
-
-    public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
-
-    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
-
-    private static final String[] PARSE_PATTERNS = {
-        "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
-        "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
-        "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
-
-    /**
-     * 鑾峰彇褰撳墠Date鍨嬫棩鏈�
-     *
-     * @return Date() 褰撳墠鏃ユ湡
-     */
-    public static Date getNowDate() {
-        return new Date();
-    }
-
-    /**
-     * 鑾峰彇褰撳墠鏃ユ湡, 榛樿鏍煎紡涓簓yyy-MM-dd
-     *
-     * @return String
-     */
-    public static String getDate() {
-        return dateTimeNow(YYYY_MM_DD);
-    }
-
-    public static String getTime() {
-        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
-    }
-
-    public static String dateTimeNow() {
-        return dateTimeNow(YYYYMMDDHHMMSS);
-    }
-
-    public static String dateTimeNow(final String format) {
-        return parseDateToStr(format, new Date());
-    }
-
-    public static String dateTime(final Date date) {
-        return parseDateToStr(YYYY_MM_DD, date);
-    }
-
-    public static String parseDateToStr(final String format, final Date date) {
-        return new SimpleDateFormat(format).format(date);
-    }
-
-    public static Date dateTime(final String format, final String ts) {
-        try {
-            return new SimpleDateFormat(format).parse(ts);
-        } catch (ParseException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * 鏃ユ湡璺緞 鍗冲勾/鏈�/鏃� 濡�2018/08/08
-     */
-    public static String datePath() {
-        Date now = new Date();
-        return DateFormatUtils.format(now, "yyyy/MM/dd");
-    }
-
-    /**
-     * 鏃ユ湡璺緞 鍗冲勾/鏈�/鏃� 濡�20180808
-     */
-    public static String dateTime() {
-        Date now = new Date();
-        return DateFormatUtils.format(now, "yyyyMMdd");
-    }
-
-    /**
-     * 鏃ユ湡鍨嬪瓧绗︿覆杞寲涓烘棩鏈� 鏍煎紡
-     */
-    public static Date parseDate(Object str) {
-        if (str == null) {
-            return null;
-        }
-        try {
-            return parseDate(str.toString(), PARSE_PATTERNS);
-        } catch (ParseException e) {
-            return null;
-        }
-    }
-
-    /**
-     * 鑾峰彇鏈嶅姟鍣ㄥ惎鍔ㄦ椂闂�
-     */
-    public static Date getServerStartDate() {
-        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
-        return new Date(time);
-    }
-
-    /**
-     * 璁$畻鐩稿樊澶╂暟
-     */
-    public static int differentDaysByMillisecond(Date date1, Date date2) {
-        return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
-    }
-
-    /**
-     * 璁$畻涓や釜鏃堕棿宸�
-     */
-    public static String getDatePoor(Date endDate, Date nowDate) {
-        long nd = 1000 * 24 * 60 * 60;
-        long nh = 1000 * 60 * 60;
-        long nm = 1000 * 60;
-        // long ns = 1000;
-        // 鑾峰緱涓や釜鏃堕棿鐨勬绉掓椂闂村樊寮�
-        long diff = endDate.getTime() - nowDate.getTime();
-        // 璁$畻宸灏戝ぉ
-        long day = diff / nd;
-        // 璁$畻宸灏戝皬鏃�
-        long hour = diff % nd / nh;
-        // 璁$畻宸灏戝垎閽�
-        long min = diff % nd % nh / nm;
-        // 璁$畻宸灏戠//杈撳嚭缁撴灉
-        // long sec = diff % nd % nh % nm / ns;
-        return day + "澶�" + hour + "灏忔椂" + min + "鍒嗛挓";
-    }
-
-    /**
-     * 澧炲姞 LocalDateTime ==> Date
-     */
-    public static Date toDate(LocalDateTime temporalAccessor) {
-        ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
-        return Date.from(zdt.toInstant());
-    }
-
-    /**
-     * 澧炲姞 LocalDate ==> Date
-     */
-    public static Date toDate(LocalDate temporalAccessor) {
-        LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
-        ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
-        return Date.from(zdt.toInstant());
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/MapstructUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/MapstructUtils.java
deleted file mode 100644
index bd2c15b..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/MapstructUtils.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package com.ruoyi.common.core.utils;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.map.MapUtil;
-import cn.hutool.core.util.ObjectUtil;
-import io.github.linpeilie.Converter;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * Mapstruct 宸ュ叿绫�
- * <p>鍙傝�冩枃妗o細<a href="https://mapstruct.plus/guide/quick-start">mapstruct-plus</a></p>
- *
- * @author Michelle.Chung
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class MapstructUtils {
-
-    private final static Converter CONVERTER = SpringUtils.getBean(Converter.class);
-
-    /**
-     * 灏� T 绫诲瀷瀵硅薄锛岃浆鎹负 desc 绫诲瀷鐨勫璞″苟杩斿洖
-     *
-     * @param source 鏁版嵁鏉ユ簮瀹炰綋
-     * @param desc   鎻忚堪瀵硅薄 杞崲鍚庣殑瀵硅薄
-     * @return desc
-     */
-    public static <T, V> V convert(T source, Class<V> desc) {
-        if (ObjectUtil.isNull(source)) {
-            return null;
-        }
-        if (ObjectUtil.isNull(desc)) {
-            return null;
-        }
-        return CONVERTER.convert(source, desc);
-    }
-
-    /**
-     * 灏� T 绫诲瀷瀵硅薄锛屾寜鐓ч厤缃殑鏄犲皠瀛楁瑙勫垯锛岀粰 desc 绫诲瀷鐨勫璞¤祴鍊煎苟杩斿洖 desc 瀵硅薄
-     *
-     * @param source 鏁版嵁鏉ユ簮瀹炰綋
-     * @param desc   杞崲鍚庣殑瀵硅薄
-     * @return desc
-     */
-    public static <T, V> V convert(T source, V desc) {
-        if (ObjectUtil.isNull(source)) {
-            return null;
-        }
-        if (ObjectUtil.isNull(desc)) {
-            return null;
-        }
-        return CONVERTER.convert(source, desc);
-    }
-
-    /**
-     * 灏� T 绫诲瀷鐨勯泦鍚堬紝杞崲涓� desc 绫诲瀷鐨勯泦鍚堝苟杩斿洖
-     *
-     * @param sourceList 鏁版嵁鏉ユ簮瀹炰綋鍒楄〃
-     * @param desc       鎻忚堪瀵硅薄 杞崲鍚庣殑瀵硅薄
-     * @return desc
-     */
-    public static <T, V> List<V> convert(List<T> sourceList, Class<V> desc) {
-        if (ObjectUtil.isNull(sourceList)) {
-            return null;
-        }
-        if (CollUtil.isEmpty(sourceList)) {
-            return CollUtil.newArrayList();
-        }
-        return CONVERTER.convert(sourceList, desc);
-    }
-
-    /**
-     * 灏� Map 杞崲涓� beanClass 绫诲瀷鐨勯泦鍚堝苟杩斿洖
-     *
-     * @param map       鏁版嵁鏉ユ簮
-     * @param beanClass bean绫�
-     * @return bean瀵硅薄
-     */
-    public static <T> T convert(Map<String, Object> map, Class<T> beanClass) {
-        if (MapUtil.isEmpty(map)) {
-            return null;
-        }
-        if (ObjectUtil.isNull(beanClass)) {
-            return null;
-        }
-        return CONVERTER.convert(map, beanClass);
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/MessageUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/MessageUtils.java
deleted file mode 100644
index 24928f8..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/MessageUtils.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.ruoyi.common.core.utils;
-
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import org.springframework.context.MessageSource;
-import org.springframework.context.i18n.LocaleContextHolder;
-
-/**
- * 鑾峰彇i18n璧勬簮鏂囦欢
- *
- * @author Lion Li
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class MessageUtils {
-
-    private static final MessageSource MESSAGE_SOURCE = SpringUtils.getBean(MessageSource.class);
-
-    /**
-     * 鏍规嵁娑堟伅閿拰鍙傛暟 鑾峰彇娑堟伅 濮旀墭缁檚pring messageSource
-     *
-     * @param code 娑堟伅閿�
-     * @param args 鍙傛暟
-     * @return 鑾峰彇鍥介檯鍖栫炕璇戝��
-     */
-    public static String message(String code, Object... args) {
-        return MESSAGE_SOURCE.getMessage(code, args, LocaleContextHolder.getLocale());
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ServletUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ServletUtils.java
deleted file mode 100644
index 99bb1da..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ServletUtils.java
+++ /dev/null
@@ -1,193 +0,0 @@
-package com.ruoyi.common.core.utils;
-
-import cn.hutool.core.convert.Convert;
-import cn.hutool.extra.servlet.JakartaServletUtil;
-import cn.hutool.http.HttpStatus;
-import jakarta.servlet.ServletRequest;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import jakarta.servlet.http.HttpSession;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import org.springframework.http.MediaType;
-import org.springframework.web.context.request.RequestAttributes;
-import org.springframework.web.context.request.RequestContextHolder;
-import org.springframework.web.context.request.ServletRequestAttributes;
-
-import java.io.IOException;
-import java.net.URLDecoder;
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * 瀹㈡埛绔伐鍏风被
- *
- * @author ruoyi
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class ServletUtils extends JakartaServletUtil {
-
-    /**
-     * 鑾峰彇String鍙傛暟
-     */
-    public static String getParameter(String name) {
-        return getRequest().getParameter(name);
-    }
-
-    /**
-     * 鑾峰彇String鍙傛暟
-     */
-    public static String getParameter(String name, String defaultValue) {
-        return Convert.toStr(getRequest().getParameter(name), defaultValue);
-    }
-
-    /**
-     * 鑾峰彇Integer鍙傛暟
-     */
-    public static Integer getParameterToInt(String name) {
-        return Convert.toInt(getRequest().getParameter(name));
-    }
-
-    /**
-     * 鑾峰彇Integer鍙傛暟
-     */
-    public static Integer getParameterToInt(String name, Integer defaultValue) {
-        return Convert.toInt(getRequest().getParameter(name), defaultValue);
-    }
-
-    /**
-     * 鑾峰彇Boolean鍙傛暟
-     */
-    public static Boolean getParameterToBool(String name) {
-        return Convert.toBool(getRequest().getParameter(name));
-    }
-
-    /**
-     * 鑾峰彇Boolean鍙傛暟
-     */
-    public static Boolean getParameterToBool(String name, Boolean defaultValue) {
-        return Convert.toBool(getRequest().getParameter(name), defaultValue);
-    }
-
-    /**
-     * 鑾峰緱鎵�鏈夎姹傚弬鏁�
-     *
-     * @param request 璇锋眰瀵硅薄{@link ServletRequest}
-     * @return Map
-     */
-    public static Map<String, String[]> getParams(ServletRequest request) {
-        final Map<String, String[]> map = request.getParameterMap();
-        return Collections.unmodifiableMap(map);
-    }
-
-    /**
-     * 鑾峰緱鎵�鏈夎姹傚弬鏁�
-     *
-     * @param request 璇锋眰瀵硅薄{@link ServletRequest}
-     * @return Map
-     */
-    public static Map<String, String> getParamMap(ServletRequest request) {
-        Map<String, String> params = new HashMap<>();
-        for (Map.Entry<String, String[]> entry : getParams(request).entrySet()) {
-            params.put(entry.getKey(), StringUtils.join(entry.getValue(), StringUtils.SEPARATOR));
-        }
-        return params;
-    }
-
-    /**
-     * 鑾峰彇request
-     */
-    public static HttpServletRequest getRequest() {
-        return getRequestAttributes().getRequest();
-    }
-
-    /**
-     * 鑾峰彇response
-     */
-    public static HttpServletResponse getResponse() {
-        return getRequestAttributes().getResponse();
-    }
-
-    /**
-     * 鑾峰彇session
-     */
-    public static HttpSession getSession() {
-        return getRequest().getSession();
-    }
-
-    public static ServletRequestAttributes getRequestAttributes() {
-        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
-        return (ServletRequestAttributes) attributes;
-    }
-
-    /**
-     * 灏嗗瓧绗︿覆娓叉煋鍒板鎴风
-     *
-     * @param response 娓叉煋瀵硅薄
-     * @param string   寰呮覆鏌撶殑瀛楃涓�
-     */
-    public static void renderString(HttpServletResponse response, String string) {
-        try {
-            response.setStatus(HttpStatus.HTTP_OK);
-            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
-            response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
-            response.getWriter().print(string);
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     * 鏄惁鏄疉jax寮傛璇锋眰
-     *
-     * @param request
-     */
-    public static boolean isAjaxRequest(HttpServletRequest request) {
-
-        String accept = request.getHeader("accept");
-        if (accept != null && accept.contains(MediaType.APPLICATION_JSON_VALUE)) {
-            return true;
-        }
-
-        String xRequestedWith = request.getHeader("X-Requested-With");
-        if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) {
-            return true;
-        }
-
-        String uri = request.getRequestURI();
-        if (StringUtils.equalsAnyIgnoreCase(uri, ".json", ".xml")) {
-            return true;
-        }
-
-        String ajax = request.getParameter("__ajax");
-        return StringUtils.equalsAnyIgnoreCase(ajax, "json", "xml");
-    }
-
-    public static String getClientIP() {
-        return getClientIP(getRequest());
-    }
-
-    /**
-     * 鍐呭缂栫爜
-     *
-     * @param str 鍐呭
-     * @return 缂栫爜鍚庣殑鍐呭
-     */
-    public static String urlEncode(String str) {
-        return URLEncoder.encode(str, StandardCharsets.UTF_8);
-    }
-
-    /**
-     * 鍐呭瑙g爜
-     *
-     * @param str 鍐呭
-     * @return 瑙g爜鍚庣殑鍐呭
-     */
-    public static String urlDecode(String str) {
-        return URLDecoder.decode(str, StandardCharsets.UTF_8);
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/SpringUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/SpringUtils.java
deleted file mode 100644
index b4d8208..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/SpringUtils.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.ruoyi.common.core.utils;
-
-import cn.hutool.extra.spring.SpringUtil;
-import org.springframework.aop.framework.AopContext;
-import org.springframework.beans.factory.NoSuchBeanDefinitionException;
-import org.springframework.context.ApplicationContext;
-import org.springframework.stereotype.Component;
-
-/**
- * spring宸ュ叿绫�
- *
- * @author Lion Li
- */
-@Component
-public final class SpringUtils extends SpringUtil {
-
-    /**
-     * 濡傛灉BeanFactory鍖呭惈涓�涓笌鎵�缁欏悕绉板尮閰嶇殑bean瀹氫箟锛屽垯杩斿洖true
-     */
-    public static boolean containsBean(String name) {
-        return getBeanFactory().containsBean(name);
-    }
-
-    /**
-     * 鍒ゆ柇浠ョ粰瀹氬悕瀛楁敞鍐岀殑bean瀹氫箟鏄竴涓猻ingleton杩樻槸涓�涓猵rototype銆�
-     * 濡傛灉涓庣粰瀹氬悕瀛楃浉搴旂殑bean瀹氫箟娌℃湁琚壘鍒帮紝灏嗕細鎶涘嚭涓�涓紓甯革紙NoSuchBeanDefinitionException锛�
-     */
-    public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
-        return getBeanFactory().isSingleton(name);
-    }
-
-    /**
-     * @return Class 娉ㄥ唽瀵硅薄鐨勭被鍨�
-     */
-    public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
-        return getBeanFactory().getType(name);
-    }
-
-    /**
-     * 濡傛灉缁欏畾鐨刡ean鍚嶅瓧鍦╞ean瀹氫箟涓湁鍒悕锛屽垯杩斿洖杩欎簺鍒悕
-     */
-    public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
-        return getBeanFactory().getAliases(name);
-    }
-
-    /**
-     * 鑾峰彇aop浠g悊瀵硅薄
-     */
-    @SuppressWarnings("unchecked")
-    public static <T> T getAopProxy(T invoker) {
-        return (T) AopContext.currentProxy();
-    }
-
-
-    /**
-     * 鑾峰彇spring涓婁笅鏂�
-     */
-    public static ApplicationContext context() {
-        return getApplicationContext();
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/StreamUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/StreamUtils.java
deleted file mode 100644
index 28fce35..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/StreamUtils.java
+++ /dev/null
@@ -1,254 +0,0 @@
-package com.ruoyi.common.core.utils;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.map.MapUtil;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-
-import java.util.*;
-import java.util.function.BiFunction;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-/**
- * stream 娴佸伐鍏风被
- *
- * @author Lion Li
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class StreamUtils {
-
-    /**
-     * 灏哻ollection杩囨护
-     *
-     * @param collection 闇�瑕佽浆鍖栫殑闆嗗悎
-     * @param function   杩囨护鏂规硶
-     * @return 杩囨护鍚庣殑list
-     */
-    public static <E> List<E> filter(Collection<E> collection, Predicate<E> function) {
-        if (CollUtil.isEmpty(collection)) {
-            return CollUtil.newArrayList();
-        }
-        // 娉ㄦ剰姝ゅ涓嶈浣跨敤 .toList() 鏂拌娉� 鍥犱负杩斿洖鐨勬槸涓嶅彲鍙楲ist 浼氬鑷村簭鍒楀寲闂
-        return collection.stream().filter(function).collect(Collectors.toList());
-    }
-
-    /**
-     * 灏哻ollection鎷兼帴
-     *
-     * @param collection 闇�瑕佽浆鍖栫殑闆嗗悎
-     * @param function   鎷兼帴鏂规硶
-     * @return 鎷兼帴鍚庣殑list
-     */
-    public static <E> String join(Collection<E> collection, Function<E, String> function) {
-        return join(collection, function, StringUtils.SEPARATOR);
-    }
-
-    /**
-     * 灏哻ollection鎷兼帴
-     *
-     * @param collection 闇�瑕佽浆鍖栫殑闆嗗悎
-     * @param function   鎷兼帴鏂规硶
-     * @param delimiter  鎷兼帴绗�
-     * @return 鎷兼帴鍚庣殑list
-     */
-    public static <E> String join(Collection<E> collection, Function<E, String> function, CharSequence delimiter) {
-        if (CollUtil.isEmpty(collection)) {
-            return StringUtils.EMPTY;
-        }
-        return collection.stream().map(function).filter(Objects::nonNull).collect(Collectors.joining(delimiter));
-    }
-
-    /**
-     * 灏哻ollection鎺掑簭
-     *
-     * @param collection 闇�瑕佽浆鍖栫殑闆嗗悎
-     * @param comparing  鎺掑簭鏂规硶
-     * @return 鎺掑簭鍚庣殑list
-     */
-    public static <E> List<E> sorted(Collection<E> collection, Comparator<E> comparing) {
-        if (CollUtil.isEmpty(collection)) {
-            return CollUtil.newArrayList();
-        }
-        // 娉ㄦ剰姝ゅ涓嶈浣跨敤 .toList() 鏂拌娉� 鍥犱负杩斿洖鐨勬槸涓嶅彲鍙楲ist 浼氬鑷村簭鍒楀寲闂
-        return collection.stream().sorted(comparing).collect(Collectors.toList());
-    }
-
-    /**
-     * 灏哻ollection杞寲涓虹被鍨嬩笉鍙樼殑map<br>
-     * <B>{@code Collection<V>  ---->  Map<K,V>}</B>
-     *
-     * @param collection 闇�瑕佽浆鍖栫殑闆嗗悎
-     * @param key        V绫诲瀷杞寲涓篕绫诲瀷鐨刲ambda鏂规硶
-     * @param <V>        collection涓殑娉涘瀷
-     * @param <K>        map涓殑key绫诲瀷
-     * @return 杞寲鍚庣殑map
-     */
-    public static <V, K> Map<K, V> toIdentityMap(Collection<V> collection, Function<V, K> key) {
-        if (CollUtil.isEmpty(collection)) {
-            return MapUtil.newHashMap();
-        }
-        return collection.stream().collect(Collectors.toMap(key, Function.identity(), (l, r) -> l));
-    }
-
-    /**
-     * 灏咰ollection杞寲涓簃ap(value绫诲瀷涓巆ollection鐨勬硾鍨嬩笉鍚�)<br>
-     * <B>{@code Collection<E> -----> Map<K,V>  }</B>
-     *
-     * @param collection 闇�瑕佽浆鍖栫殑闆嗗悎
-     * @param key        E绫诲瀷杞寲涓篕绫诲瀷鐨刲ambda鏂规硶
-     * @param value      E绫诲瀷杞寲涓篤绫诲瀷鐨刲ambda鏂规硶
-     * @param <E>        collection涓殑娉涘瀷
-     * @param <K>        map涓殑key绫诲瀷
-     * @param <V>        map涓殑value绫诲瀷
-     * @return 杞寲鍚庣殑map
-     */
-    public static <E, K, V> Map<K, V> toMap(Collection<E> collection, Function<E, K> key, Function<E, V> value) {
-        if (CollUtil.isEmpty(collection)) {
-            return MapUtil.newHashMap();
-        }
-        return collection.stream().collect(Collectors.toMap(key, value, (l, r) -> l));
-    }
-
-    /**
-     * 灏哻ollection鎸夌収瑙勫垯(姣斿鏈夌浉鍚岀殑鐝骇id)鍒嗙被鎴恗ap<br>
-     * <B>{@code Collection<E> -------> Map<K,List<E>> } </B>
-     *
-     * @param collection 闇�瑕佸垎绫荤殑闆嗗悎
-     * @param key        鍒嗙被鐨勮鍒�
-     * @param <E>        collection涓殑娉涘瀷
-     * @param <K>        map涓殑key绫诲瀷
-     * @return 鍒嗙被鍚庣殑map
-     */
-    public static <E, K> Map<K, List<E>> groupByKey(Collection<E> collection, Function<E, K> key) {
-        if (CollUtil.isEmpty(collection)) {
-            return MapUtil.newHashMap();
-        }
-        return collection
-            .stream()
-            .collect(Collectors.groupingBy(key, LinkedHashMap::new, Collectors.toList()));
-    }
-
-    /**
-     * 灏哻ollection鎸夌収涓や釜瑙勫垯(姣斿鏈夌浉鍚岀殑骞寸骇id,鐝骇id)鍒嗙被鎴愬弻灞俶ap<br>
-     * <B>{@code Collection<E>  --->  Map<T,Map<U,List<E>>> } </B>
-     *
-     * @param collection 闇�瑕佸垎绫荤殑闆嗗悎
-     * @param key1       绗竴涓垎绫荤殑瑙勫垯
-     * @param key2       绗簩涓垎绫荤殑瑙勫垯
-     * @param <E>        闆嗗悎鍏冪礌绫诲瀷
-     * @param <K>        绗竴涓猰ap涓殑key绫诲瀷
-     * @param <U>        绗簩涓猰ap涓殑key绫诲瀷
-     * @return 鍒嗙被鍚庣殑map
-     */
-    public static <E, K, U> Map<K, Map<U, List<E>>> groupBy2Key(Collection<E> collection, Function<E, K> key1, Function<E, U> key2) {
-        if (CollUtil.isEmpty(collection)) {
-            return MapUtil.newHashMap();
-        }
-        return collection
-            .stream()
-            .collect(Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.groupingBy(key2, LinkedHashMap::new, Collectors.toList())));
-    }
-
-    /**
-     * 灏哻ollection鎸夌収涓や釜瑙勫垯(姣斿鏈夌浉鍚岀殑骞寸骇id,鐝骇id)鍒嗙被鎴愬弻灞俶ap<br>
-     * <B>{@code Collection<E>  --->  Map<T,Map<U,E>> } </B>
-     *
-     * @param collection 闇�瑕佸垎绫荤殑闆嗗悎
-     * @param key1       绗竴涓垎绫荤殑瑙勫垯
-     * @param key2       绗簩涓垎绫荤殑瑙勫垯
-     * @param <T>        绗竴涓猰ap涓殑key绫诲瀷
-     * @param <U>        绗簩涓猰ap涓殑key绫诲瀷
-     * @param <E>        collection涓殑娉涘瀷
-     * @return 鍒嗙被鍚庣殑map
-     */
-    public static <E, T, U> Map<T, Map<U, E>> group2Map(Collection<E> collection, Function<E, T> key1, Function<E, U> key2) {
-        if (CollUtil.isEmpty(collection) || key1 == null || key2 == null) {
-            return MapUtil.newHashMap();
-        }
-        return collection
-            .stream()
-            .collect(Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.toMap(key2, Function.identity(), (l, r) -> l)));
-    }
-
-    /**
-     * 灏哻ollection杞寲涓篖ist闆嗗悎锛屼絾鏄袱鑰呯殑娉涘瀷涓嶅悓<br>
-     * <B>{@code Collection<E>  ------>  List<T> } </B>
-     *
-     * @param collection 闇�瑕佽浆鍖栫殑闆嗗悎
-     * @param function   collection涓殑娉涘瀷杞寲涓簂ist娉涘瀷鐨刲ambda琛ㄨ揪寮�
-     * @param <E>        collection涓殑娉涘瀷
-     * @param <T>        List涓殑娉涘瀷
-     * @return 杞寲鍚庣殑list
-     */
-    public static <E, T> List<T> toList(Collection<E> collection, Function<E, T> function) {
-        if (CollUtil.isEmpty(collection)) {
-            return CollUtil.newArrayList();
-        }
-        return collection
-            .stream()
-            .map(function)
-            .filter(Objects::nonNull)
-            // 娉ㄦ剰姝ゅ涓嶈浣跨敤 .toList() 鏂拌娉� 鍥犱负杩斿洖鐨勬槸涓嶅彲鍙楲ist 浼氬鑷村簭鍒楀寲闂
-            .collect(Collectors.toList());
-    }
-
-    /**
-     * 灏哻ollection杞寲涓篠et闆嗗悎锛屼絾鏄袱鑰呯殑娉涘瀷涓嶅悓<br>
-     * <B>{@code Collection<E>  ------>  Set<T> } </B>
-     *
-     * @param collection 闇�瑕佽浆鍖栫殑闆嗗悎
-     * @param function   collection涓殑娉涘瀷杞寲涓簊et娉涘瀷鐨刲ambda琛ㄨ揪寮�
-     * @param <E>        collection涓殑娉涘瀷
-     * @param <T>        Set涓殑娉涘瀷
-     * @return 杞寲鍚庣殑Set
-     */
-    public static <E, T> Set<T> toSet(Collection<E> collection, Function<E, T> function) {
-        if (CollUtil.isEmpty(collection) || function == null) {
-            return CollUtil.newHashSet();
-        }
-        return collection
-            .stream()
-            .map(function)
-            .filter(Objects::nonNull)
-            .collect(Collectors.toSet());
-    }
-
-
-    /**
-     * 鍚堝苟涓や釜鐩稿悓key绫诲瀷鐨刴ap
-     *
-     * @param map1  绗竴涓渶瑕佸悎骞剁殑 map
-     * @param map2  绗簩涓渶瑕佸悎骞剁殑 map
-     * @param merge 鍚堝苟鐨刲ambda锛屽皢key  value1 value2鍚堝苟鎴愭渶缁堢殑绫诲瀷,娉ㄦ剰value鍙兘涓虹┖鐨勬儏鍐�
-     * @param <K>   map涓殑key绫诲瀷
-     * @param <X>   绗竴涓� map鐨剉alue绫诲瀷
-     * @param <Y>   绗簩涓� map鐨剉alue绫诲瀷
-     * @param <V>   鏈�缁坢ap鐨剉alue绫诲瀷
-     * @return 鍚堝苟鍚庣殑map
-     */
-    public static <K, X, Y, V> Map<K, V> merge(Map<K, X> map1, Map<K, Y> map2, BiFunction<X, Y, V> merge) {
-        if (MapUtil.isEmpty(map1) && MapUtil.isEmpty(map2)) {
-            return MapUtil.newHashMap();
-        } else if (MapUtil.isEmpty(map1)) {
-            map1 = MapUtil.newHashMap();
-        } else if (MapUtil.isEmpty(map2)) {
-            map2 = MapUtil.newHashMap();
-        }
-        Set<K> key = new HashSet<>();
-        key.addAll(map1.keySet());
-        key.addAll(map2.keySet());
-        Map<K, V> map = new HashMap<>();
-        for (K t : key) {
-            X x = map1.get(t);
-            Y y = map2.get(t);
-            V z = merge.apply(x, y);
-            if (z != null) {
-                map.put(t, z);
-            }
-        }
-        return map;
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/StringUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/StringUtils.java
deleted file mode 100644
index 5b1c8ca..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/StringUtils.java
+++ /dev/null
@@ -1,321 +0,0 @@
-package com.ruoyi.common.core.utils;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.convert.Convert;
-import cn.hutool.core.lang.Validator;
-import cn.hutool.core.util.StrUtil;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import org.springframework.util.AntPathMatcher;
-
-import java.util.*;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-/**
- * 瀛楃涓插伐鍏风被
- *
- * @author Lion Li
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class StringUtils extends org.apache.commons.lang3.StringUtils {
-
-    public static final String SEPARATOR = ",";
-
-    /**
-     * 鑾峰彇鍙傛暟涓嶄负绌哄��
-     *
-     * @param str defaultValue 瑕佸垽鏂殑value
-     * @return value 杩斿洖鍊�
-     */
-    public static String blankToDefault(String str, String defaultValue) {
-        return StrUtil.blankToDefault(str, defaultValue);
-    }
-
-    /**
-     * * 鍒ゆ柇涓�涓瓧绗︿覆鏄惁涓虹┖涓�
-     *
-     * @param str String
-     * @return true锛氫负绌� false锛氶潪绌�
-     */
-    public static boolean isEmpty(String str) {
-        return StrUtil.isEmpty(str);
-    }
-
-    /**
-     * * 鍒ゆ柇涓�涓瓧绗︿覆鏄惁涓洪潪绌轰覆
-     *
-     * @param str String
-     * @return true锛氶潪绌轰覆 false锛氱┖涓�
-     */
-    public static boolean isNotEmpty(String str) {
-        return !isEmpty(str);
-    }
-
-    /**
-     * 鍘荤┖鏍�
-     */
-    public static String trim(String str) {
-        return StrUtil.trim(str);
-    }
-
-    /**
-     * 鎴彇瀛楃涓�
-     *
-     * @param str   瀛楃涓�
-     * @param start 寮�濮�
-     * @return 缁撴灉
-     */
-    public static String substring(final String str, int start) {
-        return substring(str, start, str.length());
-    }
-
-    /**
-     * 鎴彇瀛楃涓�
-     *
-     * @param str   瀛楃涓�
-     * @param start 寮�濮�
-     * @param end   缁撴潫
-     * @return 缁撴灉
-     */
-    public static String substring(final String str, int start, int end) {
-        return StrUtil.sub(str, start, end);
-    }
-
-    /**
-     * 鏍煎紡鍖栨枃鏈�, {} 琛ㄧず鍗犱綅绗�<br>
-     * 姝ゆ柟娉曞彧鏄畝鍗曞皢鍗犱綅绗� {} 鎸夌収椤哄簭鏇挎崲涓哄弬鏁�<br>
-     * 濡傛灉鎯宠緭鍑� {} 浣跨敤 \\杞箟 { 鍗冲彲锛屽鏋滄兂杈撳嚭 {} 涔嬪墠鐨� \ 浣跨敤鍙岃浆涔夌 \\\\ 鍗冲彲<br>
-     * 渚嬶細<br>
-     * 閫氬父浣跨敤锛歠ormat("this is {} for {}", "a", "b") -> this is a for b<br>
-     * 杞箟{}锛� format("this is \\{} for {}", "a", "b") -> this is {} for a<br>
-     * 杞箟\锛� format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
-     *
-     * @param template 鏂囨湰妯℃澘锛岃鏇挎崲鐨勯儴鍒嗙敤 {} 琛ㄧず
-     * @param params   鍙傛暟鍊�
-     * @return 鏍煎紡鍖栧悗鐨勬枃鏈�
-     */
-    public static String format(String template, Object... params) {
-        return StrUtil.format(template, params);
-    }
-
-    /**
-     * 鏄惁涓篽ttp(s)://寮�澶�
-     *
-     * @param link 閾炬帴
-     * @return 缁撴灉
-     */
-    public static boolean ishttp(String link) {
-        return Validator.isUrl(link);
-    }
-
-    /**
-     * 瀛楃涓茶浆set
-     *
-     * @param str 瀛楃涓�
-     * @param sep 鍒嗛殧绗�
-     * @return set闆嗗悎
-     */
-    public static Set<String> str2Set(String str, String sep) {
-        return new HashSet<>(str2List(str, sep, true, false));
-    }
-
-    /**
-     * 瀛楃涓茶浆list
-     *
-     * @param str         瀛楃涓�
-     * @param sep         鍒嗛殧绗�
-     * @param filterBlank 杩囨护绾┖鐧�
-     * @param trim        鍘绘帀棣栧熬绌虹櫧
-     * @return list闆嗗悎
-     */
-    public static List<String> str2List(String str, String sep, boolean filterBlank, boolean trim) {
-        List<String> list = new ArrayList<>();
-        if (isEmpty(str)) {
-            return list;
-        }
-
-        // 杩囨护绌虹櫧瀛楃涓�
-        if (filterBlank && isBlank(str)) {
-            return list;
-        }
-        String[] split = str.split(sep);
-        for (String string : split) {
-            if (filterBlank && isBlank(string)) {
-                continue;
-            }
-            if (trim) {
-                string = trim(string);
-            }
-            list.add(string);
-        }
-
-        return list;
-    }
-
-    /**
-     * 鏌ユ壘鎸囧畾瀛楃涓叉槸鍚﹀寘鍚寚瀹氬瓧绗︿覆鍒楄〃涓殑浠绘剰涓�涓瓧绗︿覆鍚屾椂涓插拷鐣ュぇ灏忓啓
-     *
-     * @param cs                  鎸囧畾瀛楃涓�
-     * @param searchCharSequences 闇�瑕佹鏌ョ殑瀛楃涓叉暟缁�
-     * @return 鏄惁鍖呭惈浠绘剰涓�涓瓧绗︿覆
-     */
-    public static boolean containsAnyIgnoreCase(CharSequence cs, CharSequence... searchCharSequences) {
-        return StrUtil.containsAnyIgnoreCase(cs, searchCharSequences);
-    }
-
-    /**
-     * 椹煎嘲杞笅鍒掔嚎鍛藉悕
-     */
-    public static String toUnderScoreCase(String str) {
-        return StrUtil.toUnderlineCase(str);
-    }
-
-    /**
-     * 鏄惁鍖呭惈瀛楃涓�
-     *
-     * @param str  楠岃瘉瀛楃涓�
-     * @param strs 瀛楃涓茬粍
-     * @return 鍖呭惈杩斿洖true
-     */
-    public static boolean inStringIgnoreCase(String str, String... strs) {
-        return StrUtil.equalsAnyIgnoreCase(str, strs);
-    }
-
-    /**
-     * 灏嗕笅鍒掔嚎澶у啓鏂瑰紡鍛藉悕鐨勫瓧绗︿覆杞崲涓洪┘宄板紡銆傚鏋滆浆鎹㈠墠鐨勪笅鍒掔嚎澶у啓鏂瑰紡鍛藉悕鐨勫瓧绗︿覆涓虹┖锛屽垯杩斿洖绌哄瓧绗︿覆銆� 渚嬪锛欻ELLO_WORLD->HelloWorld
-     *
-     * @param name 杞崲鍓嶇殑涓嬪垝绾垮ぇ鍐欐柟寮忓懡鍚嶇殑瀛楃涓�
-     * @return 杞崲鍚庣殑椹煎嘲寮忓懡鍚嶇殑瀛楃涓�
-     */
-    public static String convertToCamelCase(String name) {
-        return StrUtil.upperFirst(StrUtil.toCamelCase(name));
-    }
-
-    /**
-     * 椹煎嘲寮忓懡鍚嶆硶 渚嬪锛歶ser_name->userName
-     */
-    public static String toCamelCase(String s) {
-        return StrUtil.toCamelCase(s);
-    }
-
-    /**
-     * 鏌ユ壘鎸囧畾瀛楃涓叉槸鍚﹀尮閰嶆寚瀹氬瓧绗︿覆鍒楄〃涓殑浠绘剰涓�涓瓧绗︿覆
-     *
-     * @param str  鎸囧畾瀛楃涓�
-     * @param strs 闇�瑕佹鏌ョ殑瀛楃涓叉暟缁�
-     * @return 鏄惁鍖归厤
-     */
-    public static boolean matches(String str, List<String> strs) {
-        if (isEmpty(str) || CollUtil.isEmpty(strs)) {
-            return false;
-        }
-        for (String pattern : strs) {
-            if (isMatch(pattern, str)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * 鍒ゆ柇url鏄惁涓庤鍒欓厤缃�:
-     * ? 琛ㄧず鍗曚釜瀛楃;
-     * * 琛ㄧず涓�灞傝矾寰勫唴鐨勪换鎰忓瓧绗︿覆锛屼笉鍙法灞傜骇;
-     * ** 琛ㄧず浠绘剰灞傝矾寰�;
-     *
-     * @param pattern 鍖归厤瑙勫垯
-     * @param url     闇�瑕佸尮閰嶇殑url
-     */
-    public static boolean isMatch(String pattern, String url) {
-        AntPathMatcher matcher = new AntPathMatcher();
-        return matcher.match(pattern, url);
-    }
-
-    /**
-     * 鏁板瓧宸﹁竟琛ラ綈0锛屼娇涔嬭揪鍒版寚瀹氶暱搴︺�傛敞鎰忥紝濡傛灉鏁板瓧杞崲涓哄瓧绗︿覆鍚庯紝闀垮害澶т簬size锛屽垯鍙繚鐣� 鏈�鍚巗ize涓瓧绗︺��
-     *
-     * @param num  鏁板瓧瀵硅薄
-     * @param size 瀛楃涓叉寚瀹氶暱搴�
-     * @return 杩斿洖鏁板瓧鐨勫瓧绗︿覆鏍煎紡锛岃瀛楃涓蹭负鎸囧畾闀垮害銆�
-     */
-    public static String padl(final Number num, final int size) {
-        return padl(num.toString(), size, '0');
-    }
-
-    /**
-     * 瀛楃涓插乏琛ラ綈銆傚鏋滃師濮嬪瓧绗︿覆s闀垮害澶т簬size锛屽垯鍙繚鐣欐渶鍚巗ize涓瓧绗︺��
-     *
-     * @param s    鍘熷瀛楃涓�
-     * @param size 瀛楃涓叉寚瀹氶暱搴�
-     * @param c    鐢ㄤ簬琛ラ綈鐨勫瓧绗�
-     * @return 杩斿洖鎸囧畾闀垮害鐨勫瓧绗︿覆锛岀敱鍘熷瓧绗︿覆宸﹁ˉ榻愭垨鎴彇寰楀埌銆�
-     */
-    public static String padl(final String s, final int size, final char c) {
-        final StringBuilder sb = new StringBuilder(size);
-        if (s != null) {
-            final int len = s.length();
-            if (s.length() <= size) {
-                sb.append(String.valueOf(c).repeat(size - len));
-                sb.append(s);
-            } else {
-                return s.substring(len - size, len);
-            }
-        } else {
-            sb.append(String.valueOf(c).repeat(Math.max(0, size)));
-        }
-        return sb.toString();
-    }
-
-    /**
-     * 鍒囧垎瀛楃涓�(鍒嗛殧绗﹂粯璁ら�楀彿)
-     *
-     * @param str 琚垏鍒嗙殑瀛楃涓�
-     * @return 鍒嗗壊鍚庣殑鏁版嵁鍒楄〃
-     */
-    public static List<String> splitList(String str) {
-        return splitTo(str, Convert::toStr);
-    }
-
-    /**
-     * 鍒囧垎瀛楃涓�
-     *
-     * @param str       琚垏鍒嗙殑瀛楃涓�
-     * @param separator 鍒嗛殧绗�
-     * @return 鍒嗗壊鍚庣殑鏁版嵁鍒楄〃
-     */
-    public static List<String> splitList(String str, String separator) {
-        return splitTo(str, separator, Convert::toStr);
-    }
-
-    /**
-     * 鍒囧垎瀛楃涓茶嚜瀹氫箟杞崲(鍒嗛殧绗﹂粯璁ら�楀彿)
-     *
-     * @param str    琚垏鍒嗙殑瀛楃涓�
-     * @param mapper 鑷畾涔夎浆鎹�
-     * @return 鍒嗗壊鍚庣殑鏁版嵁鍒楄〃
-     */
-    public static <T> List<T> splitTo(String str, Function<? super Object, T> mapper) {
-        return splitTo(str, SEPARATOR, mapper);
-    }
-
-    /**
-     * 鍒囧垎瀛楃涓茶嚜瀹氫箟杞崲
-     *
-     * @param str       琚垏鍒嗙殑瀛楃涓�
-     * @param separator 鍒嗛殧绗�
-     * @param mapper    鑷畾涔夎浆鎹�
-     * @return 鍒嗗壊鍚庣殑鏁版嵁鍒楄〃
-     */
-    public static <T> List<T> splitTo(String str, String separator, Function<? super Object, T> mapper) {
-        if (isBlank(str)) {
-            return new ArrayList<>(0);
-        }
-        return StrUtil.split(str, separator)
-            .stream()
-            .filter(Objects::nonNull)
-            .map(mapper)
-            .collect(Collectors.toList());
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/Threads.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/Threads.java
deleted file mode 100644
index 89ca662..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/Threads.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package com.ruoyi.common.core.utils;
-
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-
-import java.util.concurrent.*;
-
-/**
- * 绾跨▼鐩稿叧宸ュ叿绫�.
- *
- * @author ruoyi
- */
-@Slf4j
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class Threads {
-
-    /**
-     * sleep绛夊緟,鍗曚綅涓烘绉�
-     */
-    public static void sleep(long milliseconds) {
-        try {
-            Thread.sleep(milliseconds);
-        } catch (InterruptedException e) {
-            return;
-        }
-    }
-
-    /**
-     * 鍋滄绾跨▼姹�
-     * 鍏堜娇鐢╯hutdown, 鍋滄鎺ユ敹鏂颁换鍔″苟灏濊瘯瀹屾垚鎵�鏈夊凡瀛樺湪浠诲姟.
-     * 濡傛灉瓒呮椂, 鍒欒皟鐢╯hutdownNow, 鍙栨秷鍦╳orkQueue涓璓ending鐨勪换鍔�,骞朵腑鏂墍鏈夐樆濉炲嚱鏁�.
-     * 濡傛灉浠嶇劧瓒呮檪锛屽墖寮峰埗閫�鍑�.
-     * 鍙﹀鍦╯hutdown鏃剁嚎绋嬫湰韬璋冪敤涓柇鍋氫簡澶勭悊.
-     */
-    public static void shutdownAndAwaitTermination(ExecutorService pool) {
-        if (pool != null && !pool.isShutdown()) {
-            pool.shutdown();
-            try {
-                if (!pool.awaitTermination(120, TimeUnit.SECONDS)) {
-                    pool.shutdownNow();
-                    if (!pool.awaitTermination(120, TimeUnit.SECONDS)) {
-                        log.info("Pool did not terminate");
-                    }
-                }
-            } catch (InterruptedException ie) {
-                pool.shutdownNow();
-                Thread.currentThread().interrupt();
-            }
-        }
-    }
-
-    /**
-     * 鎵撳嵃绾跨▼寮傚父淇℃伅
-     */
-    public static void printException(Runnable r, Throwable t) {
-        if (t == null && r instanceof Future<?>) {
-            try {
-                Future<?> future = (Future<?>) r;
-                if (future.isDone()) {
-                    future.get();
-                }
-            } catch (CancellationException ce) {
-                t = ce;
-            } catch (ExecutionException ee) {
-                t = ee.getCause();
-            } catch (InterruptedException ie) {
-                Thread.currentThread().interrupt();
-            }
-        }
-        if (t != null) {
-            log.error(t.getMessage(), t);
-        }
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/TreeBuildUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/TreeBuildUtils.java
deleted file mode 100644
index 0d24945..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/TreeBuildUtils.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.ruoyi.common.core.utils;
-
-import cn.hutool.core.collection.CollUtil;
-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 com.ruoyi.common.core.utils.reflect.ReflectUtils;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-
-import java.util.List;
-
-/**
- * 鎵╁睍 hutool TreeUtil 灏佽绯荤粺鏍戞瀯寤�
- *
- * @author Lion Li
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class TreeBuildUtils extends TreeUtil {
-
-    /**
-     * 鏍规嵁鍓嶇瀹氬埗宸紓鍖栧瓧娈�
-     */
-    public static final TreeNodeConfig DEFAULT_CONFIG = TreeNodeConfig.DEFAULT_CONFIG.setNameKey("label");
-
-    public static <T, K> List<Tree<K>> build(List<T> list, NodeParser<T, K> nodeParser) {
-        if (CollUtil.isEmpty(list)) {
-            return null;
-        }
-        K k = ReflectUtils.invokeGetter(list.get(0), "parentId");
-        return TreeUtil.build(list, k, DEFAULT_CONFIG, nodeParser);
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ValidatorUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ValidatorUtils.java
deleted file mode 100644
index 7b331f0..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ValidatorUtils.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.ruoyi.common.core.utils;
-
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-
-import jakarta.validation.ConstraintViolation;
-import jakarta.validation.ConstraintViolationException;
-import jakarta.validation.Validator;
-import java.util.Set;
-
-/**
- * Validator 鏍¢獙妗嗘灦宸ュ叿
- *
- * @author Lion Li
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class ValidatorUtils {
-
-    private static final Validator VALID = SpringUtils.getBean(Validator.class);
-
-    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/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/FileUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/FileUtils.java
deleted file mode 100644
index b3b4016..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/FileUtils.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.ruoyi.common.core.utils.file;
-
-import cn.hutool.core.io.FileUtil;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
-
-/**
- * 鏂囦欢澶勭悊宸ュ叿绫�
- *
- * @author Lion Li
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class FileUtils extends FileUtil {
-
-    /**
-     * 涓嬭浇鏂囦欢鍚嶉噸鏂扮紪鐮�
-     *
-     * @param response     鍝嶅簲瀵硅薄
-     * @param realFileName 鐪熷疄鏂囦欢鍚�
-     */
-    public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) {
-        String percentEncodedFileName = percentEncode(realFileName);
-        String contentDispositionValue = "attachment; filename=%s;filename*=utf-8''%s".formatted(percentEncodedFileName, percentEncodedFileName);
-        response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename");
-        response.setHeader("Content-disposition", contentDispositionValue);
-        response.setHeader("download-filename", percentEncodedFileName);
-    }
-
-    /**
-     * 鐧惧垎鍙风紪鐮佸伐鍏锋柟娉�
-     *
-     * @param s 闇�瑕佺櫨鍒嗗彿缂栫爜鐨勫瓧绗︿覆
-     * @return 鐧惧垎鍙风紪鐮佸悗鐨勫瓧绗︿覆
-     */
-    public static String percentEncode(String s) {
-        String encode = URLEncoder.encode(s, StandardCharsets.UTF_8);
-        return encode.replaceAll("\\+", "%20");
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/MimeTypeUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/MimeTypeUtils.java
deleted file mode 100644
index 7291c0f..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/MimeTypeUtils.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.ruoyi.common.core.utils.file;
-
-/**
- * 濯掍綋绫诲瀷宸ュ叿绫�
- *
- * @author ruoyi
- */
-public class MimeTypeUtils {
-    public static final String IMAGE_PNG = "image/png";
-
-    public static final String IMAGE_JPG = "image/jpg";
-
-    public static final String IMAGE_JPEG = "image/jpeg";
-
-    public static final String IMAGE_BMP = "image/bmp";
-
-    public static final String IMAGE_GIF = "image/gif";
-
-    public static final String[] IMAGE_EXTENSION = {"bmp", "gif", "jpg", "jpeg", "png"};
-
-    public static final String[] FLASH_EXTENSION = {"swf", "flv"};
-
-    public static final String[] MEDIA_EXTENSION = {"swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg",
-        "asf", "rm", "rmvb"};
-
-    public static final String[] VIDEO_EXTENSION = {"mp4", "avi", "rmvb"};
-
-    public static final String[] DEFAULT_ALLOWED_EXTENSION = {
-        // 鍥剧墖
-        "bmp", "gif", "jpg", "jpeg", "png",
-        // word excel powerpoint
-        "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
-        // 鍘嬬缉鏂囦欢
-        "rar", "zip", "gz", "bz2",
-        // 瑙嗛鏍煎紡
-        "mp4", "avi", "rmvb",
-        // pdf
-        "pdf"};
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/AddressUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/AddressUtils.java
deleted file mode 100644
index ffef66f..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/AddressUtils.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.ruoyi.common.core.utils.ip;
-
-import cn.hutool.core.net.NetUtil;
-import cn.hutool.http.HtmlUtil;
-import com.ruoyi.common.core.utils.StringUtils;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-
-/**
- * 鑾峰彇鍦板潃绫�
- *
- * @author Lion Li
- */
-@Slf4j
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class AddressUtils {
-
-    // 鏈煡鍦板潃
-    public static final String UNKNOWN = "XX XX";
-
-    public static String getRealAddressByIP(String ip) {
-        if (StringUtils.isBlank(ip)) {
-            return UNKNOWN;
-        }
-        // 鍐呯綉涓嶆煡璇�
-        ip = "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : HtmlUtil.cleanHtmlTag(ip);
-        if (NetUtil.isInnerIP(ip)) {
-            return "鍐呯綉IP";
-        }
-        return RegionUtils.getCityInfo(ip);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/RegionUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/RegionUtils.java
deleted file mode 100644
index e9bc99a..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/RegionUtils.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.ruoyi.common.core.utils.ip;
-
-import cn.hutool.core.io.FileUtil;
-import cn.hutool.core.io.resource.ClassPathResource;
-import cn.hutool.core.util.ObjectUtil;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.utils.file.FileUtils;
-import lombok.extern.slf4j.Slf4j;
-import org.lionsoul.ip2region.xdb.Searcher;
-
-import java.io.File;
-
-/**
- * 鏍规嵁ip鍦板潃瀹氫綅宸ュ叿绫伙紝绂荤嚎鏂瑰紡
- * 鍙傝�冨湴鍧�锛�<a href="https://gitee.com/lionsoul/ip2region/tree/master/binding/java">闆嗘垚 ip2region 瀹炵幇绂荤嚎IP鍦板潃瀹氫綅搴�</a>
- *
- * @author lishuyan
- */
-@Slf4j
-public class RegionUtils {
-
-    private static final Searcher SEARCHER;
-
-    static {
-        String fileName = "/ip2region.xdb";
-        File existFile = FileUtils.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + fileName);
-        if (!FileUtils.exist(existFile)) {
-            ClassPathResource fileStream = new ClassPathResource(fileName);
-            if (ObjectUtil.isEmpty(fileStream.getStream())) {
-                throw new ServiceException("RegionUtils鍒濆鍖栧け璐ワ紝鍘熷洜锛欼P鍦板潃搴撴暟鎹笉瀛樺湪锛�");
-            }
-            FileUtils.writeFromStream(fileStream.getStream(), existFile);
-        }
-
-        String dbPath = existFile.getPath();
-
-        // 1銆佷粠 dbPath 鍔犺浇鏁翠釜 xdb 鍒板唴瀛樸��
-        byte[] cBuff;
-        try {
-            cBuff = Searcher.loadContentFromFile(dbPath);
-        } catch (Exception e) {
-            throw new ServiceException("RegionUtils鍒濆鍖栧け璐ワ紝鍘熷洜锛氫粠ip2region.xdb鏂囦欢鍔犺浇鍐呭澶辫触锛�" + e.getMessage());
-        }
-        // 2銆佷娇鐢ㄤ笂杩扮殑 cBuff 鍒涘缓涓�涓畬鍏ㄥ熀浜庡唴瀛樼殑鏌ヨ瀵硅薄銆�
-        try {
-            SEARCHER = Searcher.newWithBuffer(cBuff);
-        } catch (Exception e) {
-            throw new ServiceException("RegionUtils鍒濆鍖栧け璐ワ紝鍘熷洜锛�" + e.getMessage());
-        }
-    }
-
-    /**
-     * 鏍规嵁IP鍦板潃绂荤嚎鑾峰彇鍩庡競
-     */
-    public static String getCityInfo(String ip) {
-        try {
-            ip = ip.trim();
-            // 3銆佹墽琛屾煡璇�
-            String region = SEARCHER.search(ip);
-            return region.replace("0|", "").replace("|0", "");
-        } catch (Exception e) {
-            log.error("IP鍦板潃绂荤嚎鑾峰彇鍩庡競寮傚父 {}", ip);
-            return "鏈煡";
-        }
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/reflect/ReflectUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/reflect/ReflectUtils.java
deleted file mode 100644
index af0c560..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/reflect/ReflectUtils.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package com.ruoyi.common.core.utils.reflect;
-
-import cn.hutool.core.util.ReflectUtil;
-import com.ruoyi.common.core.utils.StringUtils;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-
-import java.lang.reflect.Method;
-
-/**
- * 鍙嶅皠宸ュ叿绫�. 鎻愪緵璋冪敤getter/setter鏂规硶, 璁块棶绉佹湁鍙橀噺, 璋冪敤绉佹湁鏂规硶, 鑾峰彇娉涘瀷绫诲瀷Class, 琚獳OP杩囩殑鐪熷疄绫荤瓑宸ュ叿鍑芥暟.
- *
- * @author Lion Li
- */
-@SuppressWarnings("rawtypes")
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class ReflectUtils extends ReflectUtil {
-
-    private static final String SETTER_PREFIX = "set";
-
-    private static final String GETTER_PREFIX = "get";
-
-    /**
-     * 璋冪敤Getter鏂规硶.
-     * 鏀寔澶氱骇锛屽锛氬璞″悕.瀵硅薄鍚�.鏂规硶
-     */
-    @SuppressWarnings("unchecked")
-    public static <E> E invokeGetter(Object obj, String propertyName) {
-        Object object = obj;
-        for (String name : StringUtils.split(propertyName, ".")) {
-            String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name);
-            object = invoke(object, getterMethodName);
-        }
-        return (E) object;
-    }
-
-    /**
-     * 璋冪敤Setter鏂规硶, 浠呭尮閰嶆柟娉曞悕銆�
-     * 鏀寔澶氱骇锛屽锛氬璞″悕.瀵硅薄鍚�.鏂规硶
-     */
-    public static <E> void invokeSetter(Object obj, String propertyName, E value) {
-        Object object = obj;
-        String[] names = StringUtils.split(propertyName, ".");
-        for (int i = 0; i < names.length; i++) {
-            if (i < names.length - 1) {
-                String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]);
-                object = invoke(object, getterMethodName);
-            } else {
-                String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]);
-                Method method = getMethodByName(object.getClass(), setterMethodName);
-                invoke(object, method, value);
-            }
-        }
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sql/SqlUtil.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sql/SqlUtil.java
deleted file mode 100644
index 4c878d3..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sql/SqlUtil.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package com.ruoyi.common.core.utils.sql;
-
-import com.ruoyi.common.core.exception.UtilException;
-import com.ruoyi.common.core.utils.StringUtils;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-
-/**
- * sql鎿嶄綔宸ュ叿绫�
- *
- * @author ruoyi
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class SqlUtil {
-
-    /**
-     * 瀹氫箟甯哥敤鐨� sql鍏抽敭瀛�
-     */
-    public static final String SQL_REGEX = "select |insert |delete |update |drop |count |exec |chr |mid |master |truncate |char |and |declare ";
-
-    /**
-     * 浠呮敮鎸佸瓧姣嶃�佹暟瀛椼�佷笅鍒掔嚎銆佺┖鏍笺�侀�楀彿銆佸皬鏁扮偣锛堟敮鎸佸涓瓧娈垫帓搴忥級
-     */
-    public static final String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+";
-
-    /**
-     * 妫�鏌ュ瓧绗︼紝闃叉娉ㄥ叆缁曡繃
-     */
-    public static String escapeOrderBySql(String value) {
-        if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) {
-            throw new UtilException("鍙傛暟涓嶇鍚堣鑼冿紝涓嶈兘杩涜鏌ヨ");
-        }
-        return value;
-    }
-
-    /**
-     * 楠岃瘉 order by 璇硶鏄惁绗﹀悎瑙勮寖
-     */
-    public static boolean isValidOrderBySql(String value) {
-        return value.matches(SQL_PATTERN);
-    }
-
-    /**
-     * SQL鍏抽敭瀛楁鏌�
-     */
-    public static void filterKeyword(String value) {
-        if (StringUtils.isEmpty(value)) {
-            return;
-        }
-        String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");
-        for (String sqlKeyword : sqlKeywords) {
-            if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1) {
-                throw new UtilException("鍙傛暟瀛樺湪SQL娉ㄥ叆椋庨櫓");
-            }
-        }
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/validate/AddGroup.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/validate/AddGroup.java
deleted file mode 100644
index e1934e1..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/validate/AddGroup.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.ruoyi.common.core.validate;
-
-/**
- * 鏍¢獙鍒嗙粍 add
- *
- * @author Lion Li
- */
-public interface AddGroup {
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/validate/EditGroup.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/validate/EditGroup.java
deleted file mode 100644
index 3c6ca7f..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/validate/EditGroup.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.ruoyi.common.core.validate;
-
-/**
- * 鏍¢獙鍒嗙粍 edit
- *
- * @author Lion Li
- */
-public interface EditGroup {
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/validate/QueryGroup.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/validate/QueryGroup.java
deleted file mode 100644
index bbbfe03..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/validate/QueryGroup.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.ruoyi.common.core.validate;
-
-/**
- * 鏍¢獙鍒嗙粍 query
- *
- * @author Lion Li
- */
-public interface QueryGroup {
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/xss/Xss.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/xss/Xss.java
deleted file mode 100644
index ee72bdb..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/xss/Xss.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.ruoyi.common.core.xss;
-
-import jakarta.validation.Constraint;
-import jakarta.validation.Payload;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * 鑷畾涔墄ss鏍¢獙娉ㄨВ
- *
- * @author Lion Li
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(value = {ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
-@Constraint(validatedBy = {XssValidator.class})
-public @interface Xss {
-
-    String message() default "涓嶅厑璁镐换浣曡剼鏈繍琛�";
-
-    Class<?>[] groups() default {};
-
-    Class<? extends Payload>[] payload() default {};
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/xss/XssValidator.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/xss/XssValidator.java
deleted file mode 100644
index c6b6c6b..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/xss/XssValidator.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.ruoyi.common.core.xss;
-
-import cn.hutool.core.util.ReUtil;
-import cn.hutool.http.HtmlUtil;
-
-import jakarta.validation.ConstraintValidator;
-import jakarta.validation.ConstraintValidatorContext;
-
-/**
- * 鑷畾涔墄ss鏍¢獙娉ㄨВ瀹炵幇
- *
- * @author Lion Li
- */
-public class XssValidator implements ConstraintValidator<Xss, String> {
-
-    @Override
-    public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
-        return !ReUtil.contains(HtmlUtil.RE_HTML_MARK, value);
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ApplicationConfig.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ApplicationConfig.java
new file mode 100644
index 0000000..07500ba
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ApplicationConfig.java
@@ -0,0 +1,16 @@
+package org.dromara.common.core.config;
+
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+
+/**
+ * 绋嬪簭娉ㄨВ閰嶇疆
+ *
+ * @author Lion Li
+ */
+@AutoConfiguration
+// 琛ㄧず閫氳繃aop妗嗘灦鏆撮湶璇ヤ唬鐞嗗璞�,AopContext鑳藉璁块棶
+@EnableAspectJAutoProxy(exposeProxy = true)
+public class ApplicationConfig {
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/AsyncConfig.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/AsyncConfig.java
new file mode 100644
index 0000000..de9a9bc
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/AsyncConfig.java
@@ -0,0 +1,54 @@
+package org.dromara.common.core.config;
+
+import cn.hutool.core.util.ArrayUtil;
+import org.dromara.common.core.exception.ServiceException;
+import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.scheduling.annotation.AsyncConfigurer;
+import org.springframework.scheduling.annotation.EnableAsync;
+
+import java.util.Arrays;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ScheduledExecutorService;
+
+/**
+ * 寮傛閰嶇疆
+ *
+ * @author Lion Li
+ */
+@EnableAsync(proxyTargetClass = true)
+@AutoConfiguration
+public class AsyncConfig implements AsyncConfigurer {
+
+    @Autowired
+    @Qualifier("scheduledExecutorService")
+    private ScheduledExecutorService scheduledExecutorService;
+
+    /**
+     * 鑷畾涔� @Async 娉ㄨВ浣跨敤绯荤粺绾跨▼姹�
+     */
+    @Override
+    public Executor getAsyncExecutor() {
+        return scheduledExecutorService;
+    }
+
+    /**
+     * 寮傛鎵ц寮傚父澶勭悊
+     */
+    @Override
+    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
+        return (throwable, method, objects) -> {
+            throwable.printStackTrace();
+            StringBuilder sb = new StringBuilder();
+            sb.append("Exception message - ").append(throwable.getMessage())
+                .append(", Method name - ").append(method.getName());
+            if (ArrayUtil.isNotEmpty(objects)) {
+                sb.append(", Parameter value - ").append(Arrays.toString(objects));
+            }
+            throw new ServiceException(sb.toString());
+        };
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/RuoYiConfig.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/RuoYiConfig.java
new file mode 100644
index 0000000..ceaa934
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/RuoYiConfig.java
@@ -0,0 +1,49 @@
+package org.dromara.common.core.config;
+
+import lombok.Data;
+import lombok.Getter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * 璇诲彇椤圭洰鐩稿叧閰嶇疆
+ *
+ * @author Lion Li
+ */
+
+@Data
+@Component
+@ConfigurationProperties(prefix = "ruoyi")
+public class RuoYiConfig {
+
+    /**
+     * 椤圭洰鍚嶇О
+     */
+    private String name;
+
+    /**
+     * 鐗堟湰
+     */
+    private String version;
+
+    /**
+     * 鐗堟潈骞翠唤
+     */
+    private String copyrightYear;
+
+    /**
+     * 瀹炰緥婕旂ず寮�鍏�
+     */
+    private boolean demoEnabled;
+
+    /**
+     * 鑾峰彇鍦板潃寮�鍏�
+     */
+    @Getter
+    private static boolean addressEnabled;
+
+    public void setAddressEnabled(boolean addressEnabled) {
+        RuoYiConfig.addressEnabled = addressEnabled;
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ThreadPoolConfig.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ThreadPoolConfig.java
new file mode 100644
index 0000000..cb3d8f7
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ThreadPoolConfig.java
@@ -0,0 +1,57 @@
+package org.dromara.common.core.config;
+
+import org.dromara.common.core.config.properties.ThreadPoolProperties;
+import org.dromara.common.core.utils.Threads;
+import org.apache.commons.lang3.concurrent.BasicThreadFactory;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadPoolExecutor;
+
+/**
+ * 绾跨▼姹犻厤缃�
+ *
+ * @author Lion Li
+ **/
+@AutoConfiguration
+@EnableConfigurationProperties(ThreadPoolProperties.class)
+public class ThreadPoolConfig {
+
+    /**
+     * 鏍稿績绾跨▼鏁� = cpu 鏍稿績鏁� + 1
+     */
+    private final int core = Runtime.getRuntime().availableProcessors() + 1;
+
+    @Bean(name = "threadPoolTaskExecutor")
+    @ConditionalOnProperty(prefix = "thread-pool", name = "enabled", havingValue = "true")
+    public ThreadPoolTaskExecutor threadPoolTaskExecutor(ThreadPoolProperties threadPoolProperties) {
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(core);
+        executor.setMaxPoolSize(core * 2);
+        executor.setQueueCapacity(threadPoolProperties.getQueueCapacity());
+        executor.setKeepAliveSeconds(threadPoolProperties.getKeepAliveSeconds());
+        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+        return executor;
+    }
+
+    /**
+     * 鎵ц鍛ㄦ湡鎬ф垨瀹氭椂浠诲姟
+     */
+    @Bean(name = "scheduledExecutorService")
+    protected ScheduledExecutorService scheduledExecutorService() {
+        return new ScheduledThreadPoolExecutor(core,
+            new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(),
+            new ThreadPoolExecutor.CallerRunsPolicy()) {
+            @Override
+            protected void afterExecute(Runnable r, Throwable t) {
+                super.afterExecute(r, t);
+                Threads.printException(r, t);
+            }
+        };
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ValidatorConfig.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ValidatorConfig.java
new file mode 100644
index 0000000..00825c2
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ValidatorConfig.java
@@ -0,0 +1,39 @@
+package org.dromara.common.core.config;
+
+import jakarta.validation.Validator;
+import org.hibernate.validator.HibernateValidator;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.context.MessageSource;
+import org.springframework.context.annotation.Bean;
+import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
+
+import java.util.Properties;
+
+/**
+ * 鏍¢獙妗嗘灦閰嶇疆绫�
+ *
+ * @author Lion Li
+ */
+@AutoConfiguration
+public class ValidatorConfig {
+
+    /**
+     * 閰嶇疆鏍¢獙妗嗘灦 蹇�熻繑鍥炴ā寮�
+     */
+    @Bean
+    public Validator validator(MessageSource messageSource) {
+        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-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/properties/ThreadPoolProperties.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/properties/ThreadPoolProperties.java
new file mode 100644
index 0000000..820564f
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/properties/ThreadPoolProperties.java
@@ -0,0 +1,30 @@
+package org.dromara.common.core.config.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * 绾跨▼姹� 閰嶇疆灞炴��
+ *
+ * @author Lion Li
+ */
+@Data
+@ConfigurationProperties(prefix = "thread-pool")
+public class ThreadPoolProperties {
+
+    /**
+     * 鏄惁寮�鍚嚎绋嬫睜
+     */
+    private boolean enabled;
+
+    /**
+     * 闃熷垪鏈�澶ч暱搴�
+     */
+    private int queueCapacity;
+
+    /**
+     * 绾跨▼姹犵淮鎶ょ嚎绋嬫墍鍏佽鐨勭┖闂叉椂闂�
+     */
+    private int keepAliveSeconds;
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheConstants.java
new file mode 100644
index 0000000..67bc8e4
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheConstants.java
@@ -0,0 +1,25 @@
+package org.dromara.common.core.constant;
+
+/**
+ * 缂撳瓨鐨刱ey 甯搁噺
+ *
+ * @author Lion Li
+ */
+public interface CacheConstants {
+
+    /**
+     * 鍦ㄧ嚎鐢ㄦ埛 redis key
+     */
+    String ONLINE_TOKEN_KEY = "online_tokens:";
+
+    /**
+     * 鍙傛暟绠$悊 cache key
+     */
+    String SYS_CONFIG_KEY = "sys_config:";
+
+    /**
+     * 瀛楀吀绠$悊 cache key
+     */
+    String SYS_DICT_KEY = "sys_dict:";
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java
new file mode 100644
index 0000000..c3425d0
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java
@@ -0,0 +1,63 @@
+package org.dromara.common.core.constant;
+
+/**
+ * 缂撳瓨缁勫悕绉板父閲�
+ * <p>
+ * key 鏍煎紡涓� cacheNames#ttl#maxIdleTime#maxSize
+ * <p>
+ * ttl 杩囨湡鏃堕棿 濡傛灉璁剧疆涓�0鍒欎笉杩囨湡 榛樿涓�0
+ * maxIdleTime 鏈�澶х┖闂叉椂闂� 鏍规嵁LRU绠楁硶娓呯悊绌洪棽鏁版嵁 濡傛灉璁剧疆涓�0鍒欎笉妫�娴� 榛樿涓�0
+ * maxSize 缁勬渶澶ч暱搴� 鏍规嵁LRU绠楁硶娓呯悊婧㈠嚭鏁版嵁 濡傛灉璁剧疆涓�0鍒欐棤闄愰暱 榛樿涓�0
+ * <p>
+ * 渚嬪瓙: test#60s銆乼est#0#60s銆乼est#0#1m#1000銆乼est#1h#0#500
+ *
+ * @author Lion Li
+ */
+public interface CacheNames {
+
+    /**
+     * 婕旂ず妗堜緥
+     */
+    String DEMO_CACHE = "demo:cache#60s#10m#20";
+
+    /**
+     * 绯荤粺閰嶇疆
+     */
+    String SYS_CONFIG = "sys_config";
+
+    /**
+     * 鏁版嵁瀛楀吀
+     */
+    String SYS_DICT = "sys_dict";
+
+    /**
+     * 绉熸埛
+     */
+    String SYS_TENANT = GlobalConstants.GLOBAL_REDIS_KEY + "sys_tenant#30d";
+
+    /**
+     * 鐢ㄦ埛璐︽埛
+     */
+    String SYS_USER_NAME = "sys_user_name#30d";
+
+    /**
+     * 閮ㄩ棬
+     */
+    String SYS_DEPT = "sys_dept#30d";
+
+    /**
+     * OSS鍐呭
+     */
+    String SYS_OSS = "sys_oss#30d";
+
+    /**
+     * OSS閰嶇疆
+     */
+    String SYS_OSS_CONFIG = "sys_oss_config";
+
+    /**
+     * 鍦ㄧ嚎鐢ㄦ埛
+     */
+    String ONLINE_TOKEN = "online_tokens";
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/Constants.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/Constants.java
new file mode 100644
index 0000000..cdbda89
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/Constants.java
@@ -0,0 +1,81 @@
+package org.dromara.common.core.constant;
+
+/**
+ * 閫氱敤甯搁噺淇℃伅
+ *
+ * @author ruoyi
+ */
+public interface Constants {
+
+    /**
+     * UTF-8 瀛楃闆�
+     */
+    String UTF8 = "UTF-8";
+
+    /**
+     * GBK 瀛楃闆�
+     */
+    String GBK = "GBK";
+
+    /**
+     * www涓诲煙
+     */
+    String WWW = "www.";
+
+    /**
+     * http璇锋眰
+     */
+    String HTTP = "http://";
+
+    /**
+     * https璇锋眰
+     */
+    String HTTPS = "https://";
+
+    /**
+     * 閫氱敤鎴愬姛鏍囪瘑
+     */
+    String SUCCESS = "0";
+
+    /**
+     * 閫氱敤澶辫触鏍囪瘑
+     */
+    String FAIL = "1";
+
+    /**
+     * 鐧诲綍鎴愬姛
+     */
+    String LOGIN_SUCCESS = "Success";
+
+    /**
+     * 娉ㄩ攢
+     */
+    String LOGOUT = "Logout";
+
+    /**
+     * 娉ㄥ唽
+     */
+    String REGISTER = "Register";
+
+    /**
+     * 鐧诲綍澶辫触
+     */
+    String LOGIN_FAIL = "Error";
+
+    /**
+     * 楠岃瘉鐮佹湁鏁堟湡锛堝垎閽燂級
+     */
+    Integer CAPTCHA_EXPIRATION = 2;
+
+    /**
+     * 浠ょ墝
+     */
+    String TOKEN = "token";
+
+    /**
+     * 椤剁骇閮ㄩ棬id
+     */
+    Long TOP_PARENT_ID = 0L;
+
+}
+
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/GlobalConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/GlobalConstants.java
new file mode 100644
index 0000000..14af031
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/GlobalConstants.java
@@ -0,0 +1,39 @@
+package org.dromara.common.core.constant;
+
+/**
+ * 鍏ㄥ眬鐨刱ey甯搁噺 (涓氬姟鏃犲叧鐨刱ey)
+ *
+ * @author Lion Li
+ */
+public interface GlobalConstants {
+
+    /**
+     * 鍏ㄥ眬 redis key (涓氬姟鏃犲叧鐨刱ey)
+     */
+    String GLOBAL_REDIS_KEY = "global:";
+
+    /**
+     * 鐧诲綍鐢ㄦ埛 redis key
+     */
+    String LOGIN_TOKEN_KEY = GLOBAL_REDIS_KEY + "Authorization:login:token:";
+
+    /**
+     * 楠岃瘉鐮� redis key
+     */
+    String CAPTCHA_CODE_KEY = GLOBAL_REDIS_KEY + "captcha_codes:";
+
+    /**
+     * 闃查噸鎻愪氦 redis key
+     */
+    String REPEAT_SUBMIT_KEY = GLOBAL_REDIS_KEY + "repeat_submit:";
+
+    /**
+     * 闄愭祦 redis key
+     */
+    String RATE_LIMIT_KEY = GLOBAL_REDIS_KEY + "rate_limit:";
+
+    /**
+     * 鐧诲綍璐︽埛瀵嗙爜閿欒娆℃暟 redis key
+     */
+    String PWD_ERR_CNT_KEY = GLOBAL_REDIS_KEY + "pwd_err_cnt:";
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/HttpStatus.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/HttpStatus.java
new file mode 100644
index 0000000..85566e8
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/HttpStatus.java
@@ -0,0 +1,93 @@
+package org.dromara.common.core.constant;
+
+/**
+ * 杩斿洖鐘舵�佺爜
+ *
+ * @author Lion Li
+ */
+public interface HttpStatus {
+    /**
+     * 鎿嶄綔鎴愬姛
+     */
+    int SUCCESS = 200;
+
+    /**
+     * 瀵硅薄鍒涘缓鎴愬姛
+     */
+    int CREATED = 201;
+
+    /**
+     * 璇锋眰宸茬粡琚帴鍙�
+     */
+    int ACCEPTED = 202;
+
+    /**
+     * 鎿嶄綔宸茬粡鎵ц鎴愬姛锛屼絾鏄病鏈夎繑鍥炴暟鎹�
+     */
+    int NO_CONTENT = 204;
+
+    /**
+     * 璧勬簮宸茶绉婚櫎
+     */
+    int MOVED_PERM = 301;
+
+    /**
+     * 閲嶅畾鍚�
+     */
+    int SEE_OTHER = 303;
+
+    /**
+     * 璧勬簮娌℃湁琚慨鏀�
+     */
+    int NOT_MODIFIED = 304;
+
+    /**
+     * 鍙傛暟鍒楄〃閿欒锛堢己灏戯紝鏍煎紡涓嶅尮閰嶏級
+     */
+    int BAD_REQUEST = 400;
+
+    /**
+     * 鏈巿鏉�
+     */
+    int UNAUTHORIZED = 401;
+
+    /**
+     * 璁块棶鍙楅檺锛屾巿鏉冭繃鏈�
+     */
+    int FORBIDDEN = 403;
+
+    /**
+     * 璧勬簮锛屾湇鍔℃湭鎵惧埌
+     */
+    int NOT_FOUND = 404;
+
+    /**
+     * 涓嶅厑璁哥殑http鏂规硶
+     */
+    int BAD_METHOD = 405;
+
+    /**
+     * 璧勬簮鍐茬獊锛屾垨鑰呰祫婧愯閿�
+     */
+    int CONFLICT = 409;
+
+    /**
+     * 涓嶆敮鎸佺殑鏁版嵁锛屽獟浣撶被鍨�
+     */
+    int UNSUPPORTED_TYPE = 415;
+
+    /**
+     * 绯荤粺鍐呴儴閿欒
+     */
+    int ERROR = 500;
+
+    /**
+     * 鎺ュ彛鏈疄鐜�
+     */
+    int NOT_IMPLEMENTED = 501;
+
+    /**
+     * 绯荤粺璀﹀憡娑堟伅
+     */
+    int WARN = 601;
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/TenantConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/TenantConstants.java
new file mode 100644
index 0000000..86b63c9
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/TenantConstants.java
@@ -0,0 +1,45 @@
+package org.dromara.common.core.constant;
+
+/**
+ * 绉熸埛甯搁噺淇℃伅
+ *
+ * @author Lion Li
+ */
+public interface TenantConstants {
+
+    /**
+     * 绉熸埛姝e父鐘舵��
+     */
+    String NORMAL = "0";
+
+    /**
+     * 绉熸埛灏佺鐘舵��
+     */
+    String DISABLE = "1";
+
+    /**
+     * 瓒呯骇绠$悊鍛業D
+     */
+    Long SUPER_ADMIN_ID = 1L;
+
+    /**
+     * 瓒呯骇绠$悊鍛樿鑹� roleKey
+     */
+    String SUPER_ADMIN_ROLE_KEY = "superadmin";
+
+    /**
+     * 绉熸埛绠$悊鍛樿鑹� roleKey
+     */
+    String TENANT_ADMIN_ROLE_KEY = "admin";
+
+    /**
+     * 绉熸埛绠$悊鍛樿鑹插悕绉�
+     */
+    String TENANT_ADMIN_ROLE_NAME = "绠$悊鍛�";
+
+    /**
+     * 榛樿绉熸埛ID
+     */
+    String DEFAULT_TENANT_ID = "000000";
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/UserConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/UserConstants.java
new file mode 100644
index 0000000..c78adc2
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/UserConstants.java
@@ -0,0 +1,132 @@
+package org.dromara.common.core.constant;
+
+/**
+ * 鐢ㄦ埛甯搁噺淇℃伅
+ *
+ * @author ruoyi
+ */
+public interface UserConstants {
+
+    /**
+     * 骞冲彴鍐呯郴缁熺敤鎴风殑鍞竴鏍囧織
+     */
+    String SYS_USER = "SYS_USER";
+
+    /**
+     * 姝e父鐘舵��
+     */
+    String NORMAL = "0";
+
+    /**
+     * 寮傚父鐘舵��
+     */
+    String EXCEPTION = "1";
+
+    /**
+     * 鐢ㄦ埛姝e父鐘舵��
+     */
+    String USER_NORMAL = "0";
+
+    /**
+     * 鐢ㄦ埛灏佺鐘舵��
+     */
+    String USER_DISABLE = "1";
+
+    /**
+     * 瑙掕壊姝e父鐘舵��
+     */
+    String ROLE_NORMAL = "0";
+
+    /**
+     * 瑙掕壊灏佺鐘舵��
+     */
+    String ROLE_DISABLE = "1";
+
+    /**
+     * 閮ㄩ棬姝e父鐘舵��
+     */
+    String DEPT_NORMAL = "0";
+
+    /**
+     * 閮ㄩ棬鍋滅敤鐘舵��
+     */
+    String DEPT_DISABLE = "1";
+
+    /**
+     * 瀛楀吀姝e父鐘舵��
+     */
+    String DICT_NORMAL = "0";
+
+    /**
+     * 鏄惁涓虹郴缁熼粯璁わ紙鏄級
+     */
+    String YES = "Y";
+
+    /**
+     * 鏄惁鑿滃崟澶栭摼锛堟槸锛�
+     */
+    String YES_FRAME = "0";
+
+    /**
+     * 鏄惁鑿滃崟澶栭摼锛堝惁锛�
+     */
+    String NO_FRAME = "1";
+
+    /**
+     * 鑿滃崟姝e父鐘舵��
+     */
+    String MENU_NORMAL = "0";
+
+    /**
+     * 鑿滃崟鍋滅敤鐘舵��
+     */
+    String MENU_DISABLE = "1";
+
+    /**
+     * 鑿滃崟绫诲瀷锛堢洰褰曪級
+     */
+    String TYPE_DIR = "M";
+
+    /**
+     * 鑿滃崟绫诲瀷锛堣彍鍗曪級
+     */
+    String TYPE_MENU = "C";
+
+    /**
+     * 鑿滃崟绫诲瀷锛堟寜閽級
+     */
+    String TYPE_BUTTON = "F";
+
+    /**
+     * Layout缁勪欢鏍囪瘑
+     */
+    String LAYOUT = "Layout";
+
+    /**
+     * ParentView缁勪欢鏍囪瘑
+     */
+    String PARENT_VIEW = "ParentView";
+
+    /**
+     * InnerLink缁勪欢鏍囪瘑
+     */
+    String INNER_LINK = "InnerLink";
+
+    /**
+     * 鐢ㄦ埛鍚嶉暱搴﹂檺鍒�
+     */
+    int USERNAME_MIN_LENGTH = 2;
+    int USERNAME_MAX_LENGTH = 20;
+
+    /**
+     * 瀵嗙爜闀垮害闄愬埗
+     */
+    int PASSWORD_MIN_LENGTH = 5;
+    int PASSWORD_MAX_LENGTH = 20;
+
+    /**
+     * 瓒呯骇绠$悊鍛業D
+     */
+    Long SUPER_ADMIN_ID = 1L;
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/R.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/R.java
new file mode 100644
index 0000000..be85805
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/R.java
@@ -0,0 +1,110 @@
+package org.dromara.common.core.domain;
+
+import org.dromara.common.core.constant.HttpStatus;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 鍝嶅簲淇℃伅涓讳綋
+ *
+ * @author Lion Li
+ */
+@Data
+@NoArgsConstructor
+public class R<T> implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鎴愬姛
+     */
+    public static final int SUCCESS = 200;
+
+    /**
+     * 澶辫触
+     */
+    public static final int FAIL = 500;
+
+    private int code;
+
+    private String msg;
+
+    private T data;
+
+    public static <T> R<T> ok() {
+        return restResult(null, SUCCESS, "鎿嶄綔鎴愬姛");
+    }
+
+    public static <T> R<T> ok(T data) {
+        return restResult(data, SUCCESS, "鎿嶄綔鎴愬姛");
+    }
+
+    public static <T> R<T> ok(String msg) {
+        return restResult(null, SUCCESS, msg);
+    }
+
+    public static <T> R<T> ok(String msg, T data) {
+        return restResult(data, SUCCESS, msg);
+    }
+
+    public static <T> R<T> fail() {
+        return restResult(null, FAIL, "鎿嶄綔澶辫触");
+    }
+
+    public static <T> R<T> fail(String msg) {
+        return restResult(null, FAIL, msg);
+    }
+
+    public static <T> R<T> fail(T data) {
+        return restResult(data, FAIL, "鎿嶄綔澶辫触");
+    }
+
+    public static <T> R<T> fail(String msg, T data) {
+        return restResult(data, FAIL, msg);
+    }
+
+    public static <T> R<T> fail(int code, String msg) {
+        return restResult(null, code, msg);
+    }
+
+    /**
+     * 杩斿洖璀﹀憡娑堟伅
+     *
+     * @param msg 杩斿洖鍐呭
+     * @return 璀﹀憡娑堟伅
+     */
+    public static <T> R<T> warn(String msg) {
+        return restResult(null, HttpStatus.WARN, msg);
+    }
+
+    /**
+     * 杩斿洖璀﹀憡娑堟伅
+     *
+     * @param msg 杩斿洖鍐呭
+     * @param data 鏁版嵁瀵硅薄
+     * @return 璀﹀憡娑堟伅
+     */
+    public static <T> R<T> warn(String msg, T data) {
+        return restResult(data, HttpStatus.WARN, msg);
+    }
+
+    private static <T> R<T> restResult(T data, int code, String msg) {
+        R<T> r = new R<>();
+        r.setCode(code);
+        r.setData(data);
+        r.setMsg(msg);
+        return r;
+    }
+
+    public static <T> Boolean isError(R<T> ret) {
+        return !isSuccess(ret);
+    }
+
+    public static <T> Boolean isSuccess(R<T> ret) {
+        return R.SUCCESS == ret.getCode();
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/RoleDTO.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/RoleDTO.java
new file mode 100644
index 0000000..03d6166
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/RoleDTO.java
@@ -0,0 +1,38 @@
+package org.dromara.common.core.domain.dto;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 瑙掕壊
+ *
+ * @author Lion Li
+ */
+
+@Data
+@NoArgsConstructor
+public class RoleDTO implements Serializable {
+
+    /**
+     * 瑙掕壊ID
+     */
+    private Long roleId;
+
+    /**
+     * 瑙掕壊鍚嶇О
+     */
+    private String roleName;
+
+    /**
+     * 瑙掕壊鏉冮檺
+     */
+    private String roleKey;
+
+    /**
+     * 鏁版嵁鑼冨洿锛�1锛氭墍鏈夋暟鎹潈闄愶紱2锛氳嚜瀹氫箟鏁版嵁鏉冮檺锛�3锛氭湰閮ㄩ棬鏁版嵁鏉冮檺锛�4锛氭湰閮ㄩ棬鍙婁互涓嬫暟鎹潈闄愶紱5锛氫粎鏈汉鏁版嵁鏉冮檺锛�
+     */
+    private String dataScope;
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/UserOnlineDTO.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/UserOnlineDTO.java
new file mode 100644
index 0000000..0e8def8
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/UserOnlineDTO.java
@@ -0,0 +1,62 @@
+package org.dromara.common.core.domain.dto;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 褰撳墠鍦ㄧ嚎浼氳瘽
+ *
+ * @author ruoyi
+ */
+
+@Data
+@NoArgsConstructor
+public class UserOnlineDTO implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 浼氳瘽缂栧彿
+     */
+    private String tokenId;
+
+    /**
+     * 閮ㄩ棬鍚嶇О
+     */
+    private String deptName;
+
+    /**
+     * 鐢ㄦ埛鍚嶇О
+     */
+    private String userName;
+
+    /**
+     * 鐧诲綍IP鍦板潃
+     */
+    private String ipaddr;
+
+    /**
+     * 鐧诲綍鍦板潃
+     */
+    private String loginLocation;
+
+    /**
+     * 娴忚鍣ㄧ被鍨�
+     */
+    private String browser;
+
+    /**
+     * 鎿嶄綔绯荤粺
+     */
+    private String os;
+
+    /**
+     * 鐧诲綍鏃堕棿
+     */
+    private Long loginTime;
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/EmailLoginBody.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/EmailLoginBody.java
new file mode 100644
index 0000000..0afe010
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/EmailLoginBody.java
@@ -0,0 +1,35 @@
+package org.dromara.common.core.domain.model;
+
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+
+/**
+ * 鐭俊鐧诲綍瀵硅薄
+ *
+ * @author Lion Li
+ */
+
+@Data
+public class EmailLoginBody {
+
+    /**
+     * 绉熸埛ID
+     */
+    @NotBlank(message = "{tenant.number.not.blank}")
+    private String tenantId;
+
+    /**
+     * 閭
+     */
+    @NotBlank(message = "{user.email.not.blank}")
+    @Email(message = "{user.email.not.valid}")
+    private String email;
+
+    /**
+     * 閭code
+     */
+    @NotBlank(message = "{email.code.not.blank}")
+    private String emailCode;
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginBody.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginBody.java
new file mode 100644
index 0000000..73f678c
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginBody.java
@@ -0,0 +1,48 @@
+package org.dromara.common.core.domain.model;
+
+import org.dromara.common.core.constant.UserConstants;
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+import jakarta.validation.constraints.NotBlank;
+
+/**
+ * 鐢ㄦ埛鐧诲綍瀵硅薄
+ *
+ * @author Lion Li
+ */
+
+@Data
+public class LoginBody {
+
+    /**
+     * 绉熸埛ID
+     */
+    @NotBlank(message = "{tenant.number.not.blank}")
+    private String tenantId;
+
+    /**
+     * 鐢ㄦ埛鍚�
+     */
+    @NotBlank(message = "{user.username.not.blank}")
+    @Length(min = UserConstants.USERNAME_MIN_LENGTH, max = UserConstants.USERNAME_MAX_LENGTH, message = "{user.username.length.valid}")
+    private String username;
+
+    /**
+     * 鐢ㄦ埛瀵嗙爜
+     */
+    @NotBlank(message = "{user.password.not.blank}")
+    @Length(min = UserConstants.PASSWORD_MIN_LENGTH, max = UserConstants.PASSWORD_MAX_LENGTH, message = "{user.password.length.valid}")
+    private String password;
+
+    /**
+     * 楠岃瘉鐮�
+     */
+    private String code;
+
+    /**
+     * 鍞竴鏍囪瘑
+     */
+    private String uuid;
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginUser.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginUser.java
new file mode 100644
index 0000000..a770089
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginUser.java
@@ -0,0 +1,123 @@
+package org.dromara.common.core.domain.model;
+
+import org.dromara.common.core.domain.dto.RoleDTO;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 鐧诲綍鐢ㄦ埛韬唤鏉冮檺
+ *
+ * @author Lion Li
+ */
+
+@Data
+@NoArgsConstructor
+public class LoginUser implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 绉熸埛ID
+     */
+    private String tenantId;
+
+    /**
+     * 鐢ㄦ埛ID
+     */
+    private Long userId;
+
+    /**
+     * 閮ㄩ棬ID
+     */
+    private Long deptId;
+
+    /**
+     * 閮ㄩ棬鍚�
+     */
+    private String deptName;
+
+    /**
+     * 鐢ㄦ埛鍞竴鏍囪瘑
+     */
+    private String token;
+
+    /**
+     * 鐢ㄦ埛绫诲瀷
+     */
+    private String userType;
+
+    /**
+     * 鐧诲綍鏃堕棿
+     */
+    private Long loginTime;
+
+    /**
+     * 杩囨湡鏃堕棿
+     */
+    private Long expireTime;
+
+    /**
+     * 鐧诲綍IP鍦板潃
+     */
+    private String ipaddr;
+
+    /**
+     * 鐧诲綍鍦扮偣
+     */
+    private String loginLocation;
+
+    /**
+     * 娴忚鍣ㄧ被鍨�
+     */
+    private String browser;
+
+    /**
+     * 鎿嶄綔绯荤粺
+     */
+    private String os;
+
+    /**
+     * 鑿滃崟鏉冮檺
+     */
+    private Set<String> menuPermission;
+
+    /**
+     * 瑙掕壊鏉冮檺
+     */
+    private Set<String> rolePermission;
+
+    /**
+     * 鐢ㄦ埛鍚�
+     */
+    private String username;
+
+    /**
+     * 瑙掕壊瀵硅薄
+     */
+    private List<RoleDTO> roles;
+
+    /**
+     * 鏁版嵁鏉冮檺 褰撳墠瑙掕壊ID
+     */
+    private Long roleId;
+
+    /**
+     * 鑾峰彇鐧诲綍id
+     */
+    public String getLoginId() {
+        if (userType == null) {
+            throw new IllegalArgumentException("鐢ㄦ埛绫诲瀷涓嶈兘涓虹┖");
+        }
+        if (userId == null) {
+            throw new IllegalArgumentException("鐢ㄦ埛ID涓嶈兘涓虹┖");
+        }
+        return userType + ":" + userId;
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/RegisterBody.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/RegisterBody.java
new file mode 100644
index 0000000..6bb5359
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/RegisterBody.java
@@ -0,0 +1,17 @@
+package org.dromara.common.core.domain.model;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 鐢ㄦ埛娉ㄥ唽瀵硅薄
+ *
+ * @author Lion Li
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class RegisterBody extends LoginBody {
+
+    private String userType;
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/SmsLoginBody.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/SmsLoginBody.java
new file mode 100644
index 0000000..b67a56e
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/SmsLoginBody.java
@@ -0,0 +1,34 @@
+package org.dromara.common.core.domain.model;
+
+import lombok.Data;
+
+import jakarta.validation.constraints.NotBlank;
+
+/**
+ * 鐭俊鐧诲綍瀵硅薄
+ *
+ * @author Lion Li
+ */
+
+@Data
+public class SmsLoginBody {
+
+    /**
+     * 绉熸埛ID
+     */
+    @NotBlank(message = "{tenant.number.not.blank}")
+    private String tenantId;
+
+    /**
+     * 鎵嬫満鍙�
+     */
+    @NotBlank(message = "{user.phonenumber.not.blank}")
+    private String phonenumber;
+
+    /**
+     * 鐭俊code
+     */
+    @NotBlank(message = "{sms.code.not.blank}")
+    private String smsCode;
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/XcxLoginUser.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/XcxLoginUser.java
new file mode 100644
index 0000000..e5f3d6c
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/XcxLoginUser.java
@@ -0,0 +1,27 @@
+package org.dromara.common.core.domain.model;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+
+/**
+ * 灏忕▼搴忕櫥褰曠敤鎴疯韩浠芥潈闄�
+ *
+ * @author Lion Li
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@NoArgsConstructor
+public class XcxLoginUser extends LoginUser {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * openid
+     */
+    private String openid;
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/DeviceType.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/DeviceType.java
new file mode 100644
index 0000000..09bf44b
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/DeviceType.java
@@ -0,0 +1,32 @@
+package org.dromara.common.core.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 璁惧绫诲瀷
+ * 閽堝涓�濂� 鐢ㄦ埛浣撶郴
+ *
+ * @author Lion Li
+ */
+@Getter
+@AllArgsConstructor
+public enum DeviceType {
+
+    /**
+     * pc绔�
+     */
+    PC("pc"),
+
+    /**
+     * app绔�
+     */
+    APP("app"),
+
+    /**
+     * 灏忕▼搴忕
+     */
+    XCX("xcx");
+
+    private final String device;
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/LoginType.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/LoginType.java
new file mode 100644
index 0000000..f9cac66
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/LoginType.java
@@ -0,0 +1,44 @@
+package org.dromara.common.core.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 鐧诲綍绫诲瀷
+ *
+ * @author Lion Li
+ */
+@Getter
+@AllArgsConstructor
+public enum LoginType {
+
+    /**
+     * 瀵嗙爜鐧诲綍
+     */
+    PASSWORD("user.password.retry.limit.exceed", "user.password.retry.limit.count"),
+
+    /**
+     * 鐭俊鐧诲綍
+     */
+    SMS("sms.code.retry.limit.exceed", "sms.code.retry.limit.count"),
+
+    /**
+     * 閭鐧诲綍
+     */
+    EMAIL("email.code.retry.limit.exceed", "email.code.retry.limit.count"),
+
+    /**
+     * 灏忕▼搴忕櫥褰�
+     */
+    XCX("", "");
+
+    /**
+     * 鐧诲綍閲嶈瘯瓒呭嚭闄愬埗鎻愮ず
+     */
+    final String retryLimitExceed;
+
+    /**
+     * 鐧诲綍閲嶈瘯闄愬埗璁℃暟鎻愮ず
+     */
+    final String retryLimitCount;
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/TenantStatus.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/TenantStatus.java
new file mode 100644
index 0000000..400a399
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/TenantStatus.java
@@ -0,0 +1,30 @@
+package org.dromara.common.core.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 鐢ㄦ埛鐘舵��
+ *
+ * @author LionLi
+ */
+@Getter
+@AllArgsConstructor
+public enum TenantStatus {
+    /**
+     * 姝e父
+     */
+    OK("0", "姝e父"),
+    /**
+     * 鍋滅敤
+     */
+    DISABLE("1", "鍋滅敤"),
+    /**
+     * 鍒犻櫎
+     */
+    DELETED("2", "鍒犻櫎");
+
+    private final String code;
+    private final String info;
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/UserStatus.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/UserStatus.java
new file mode 100644
index 0000000..be7e44d
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/UserStatus.java
@@ -0,0 +1,30 @@
+package org.dromara.common.core.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 鐢ㄦ埛鐘舵��
+ *
+ * @author ruoyi
+ */
+@Getter
+@AllArgsConstructor
+public enum UserStatus {
+    /**
+     * 姝e父
+     */
+    OK("0", "姝e父"),
+    /**
+     * 鍋滅敤
+     */
+    DISABLE("1", "鍋滅敤"),
+    /**
+     * 鍒犻櫎
+     */
+    DELETED("2", "鍒犻櫎");
+
+    private final String code;
+    private final String info;
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/UserType.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/UserType.java
new file mode 100644
index 0000000..69e4753
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/UserType.java
@@ -0,0 +1,37 @@
+package org.dromara.common.core.enums;
+
+import org.dromara.common.core.utils.StringUtils;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 璁惧绫诲瀷
+ * 閽堝澶氬 鐢ㄦ埛浣撶郴
+ *
+ * @author Lion Li
+ */
+@Getter
+@AllArgsConstructor
+public enum UserType {
+
+    /**
+     * pc绔�
+     */
+    SYS_USER("sys_user"),
+
+    /**
+     * app绔�
+     */
+    APP_USER("app_user");
+
+    private final String userType;
+
+    public static UserType getUserType(String str) {
+        for (UserType value : values()) {
+            if (StringUtils.contains(str, value.getUserType())) {
+                return value;
+            }
+        }
+        throw new RuntimeException("'UserType' not found By " + str);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/DemoModeException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/DemoModeException.java
new file mode 100644
index 0000000..9916ddf
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/DemoModeException.java
@@ -0,0 +1,17 @@
+package org.dromara.common.core.exception;
+
+import java.io.Serial;
+
+/**
+ * 婕旂ず妯″紡寮傚父
+ *
+ * @author ruoyi
+ */
+public class DemoModeException extends RuntimeException {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    public DemoModeException() {
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/GlobalException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/GlobalException.java
new file mode 100644
index 0000000..6b404e6
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/GlobalException.java
@@ -0,0 +1,53 @@
+package org.dromara.common.core.exception;
+
+import java.io.Serial;
+
+/**
+ * 鍏ㄥ眬寮傚父
+ *
+ * @author ruoyi
+ */
+public class GlobalException extends RuntimeException {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 閿欒鎻愮ず
+     */
+    private String message;
+
+    /**
+     * 閿欒鏄庣粏锛屽唴閮ㄨ皟璇曢敊璇�
+     */
+    private String detailMessage;
+
+    /**
+     * 绌烘瀯閫犳柟娉曪紝閬垮厤鍙嶅簭鍒楀寲闂
+     */
+    public GlobalException() {
+    }
+
+    public GlobalException(String message) {
+        this.message = message;
+    }
+
+    public String getDetailMessage() {
+        return detailMessage;
+    }
+
+    public GlobalException setDetailMessage(String detailMessage) {
+        this.detailMessage = detailMessage;
+        return this;
+    }
+
+    @Override
+    public String getMessage() {
+        return message;
+    }
+
+    public GlobalException setMessage(String message) {
+        this.message = message;
+        return this;
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/ServiceException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/ServiceException.java
new file mode 100644
index 0000000..712e6e7
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/ServiceException.java
@@ -0,0 +1,67 @@
+package org.dromara.common.core.exception;
+
+import java.io.Serial;
+
+/**
+ * 涓氬姟寮傚父
+ *
+ * @author ruoyi
+ */
+public final class ServiceException extends RuntimeException {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 閿欒鐮�
+     */
+    private Integer code;
+
+    /**
+     * 閿欒鎻愮ず
+     */
+    private String message;
+
+    /**
+     * 閿欒鏄庣粏锛屽唴閮ㄨ皟璇曢敊璇�
+     */
+    private String detailMessage;
+
+    /**
+     * 绌烘瀯閫犳柟娉曪紝閬垮厤鍙嶅簭鍒楀寲闂
+     */
+    public ServiceException() {
+    }
+
+    public ServiceException(String message) {
+        this.message = message;
+    }
+
+    public ServiceException(String message, Integer code) {
+        this.message = message;
+        this.code = code;
+    }
+
+    public String getDetailMessage() {
+        return detailMessage;
+    }
+
+    @Override
+    public String getMessage() {
+        return message;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public ServiceException setMessage(String message) {
+        this.message = message;
+        return this;
+    }
+
+    public ServiceException setDetailMessage(String detailMessage) {
+        this.detailMessage = detailMessage;
+        return this;
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/UtilException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/UtilException.java
new file mode 100644
index 0000000..a9bf2c6
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/UtilException.java
@@ -0,0 +1,26 @@
+package org.dromara.common.core.exception;
+
+import java.io.Serial;
+
+/**
+ * 宸ュ叿绫诲紓甯�
+ *
+ * @author ruoyi
+ */
+public class UtilException extends RuntimeException {
+
+    @Serial
+    private static final long serialVersionUID = 8247610319171014183L;
+
+    public UtilException(Throwable e) {
+        super(e.getMessage(), e);
+    }
+
+    public UtilException(String message) {
+        super(message);
+    }
+
+    public UtilException(String message, Throwable throwable) {
+        super(message, throwable);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/base/BaseException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/base/BaseException.java
new file mode 100644
index 0000000..28acafd
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/base/BaseException.java
@@ -0,0 +1,79 @@
+package org.dromara.common.core.exception.base;
+
+import org.dromara.common.core.utils.MessageUtils;
+import org.dromara.common.core.utils.StringUtils;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+
+/**
+ * 鍩虹寮傚父
+ *
+ * @author ruoyi
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@NoArgsConstructor
+public class BaseException extends RuntimeException {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鎵�灞炴ā鍧�
+     */
+    private String module;
+
+    /**
+     * 閿欒鐮�
+     */
+    private String code;
+
+    /**
+     * 閿欒鐮佸搴旂殑鍙傛暟
+     */
+    private Object[] args;
+
+    /**
+     * 閿欒娑堟伅
+     */
+    private String defaultMessage;
+
+    public BaseException(String module, String code, Object[] args, String defaultMessage) {
+        this.module = module;
+        this.code = code;
+        this.args = args;
+        this.defaultMessage = defaultMessage;
+    }
+
+    public BaseException(String module, String code, Object[] args) {
+        this(module, code, args, null);
+    }
+
+    public BaseException(String module, String defaultMessage) {
+        this(module, null, null, defaultMessage);
+    }
+
+    public BaseException(String code, Object[] args) {
+        this(null, code, args, null);
+    }
+
+    public BaseException(String defaultMessage) {
+        this(null, null, null, defaultMessage);
+    }
+
+    @Override
+    public String getMessage() {
+        String message = null;
+        if (!StringUtils.isEmpty(code)) {
+            message = MessageUtils.message(code, args);
+        }
+        if (message == null) {
+            message = defaultMessage;
+        }
+        return message;
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileException.java
new file mode 100644
index 0000000..d374fc0
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileException.java
@@ -0,0 +1,21 @@
+package org.dromara.common.core.exception.file;
+
+import org.dromara.common.core.exception.base.BaseException;
+
+import java.io.Serial;
+
+/**
+ * 鏂囦欢淇℃伅寮傚父绫�
+ *
+ * @author ruoyi
+ */
+public class FileException extends BaseException {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    public FileException(String code, Object[] args) {
+        super("file", code, args, null);
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileNameLengthLimitExceededException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileNameLengthLimitExceededException.java
new file mode 100644
index 0000000..af98124
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileNameLengthLimitExceededException.java
@@ -0,0 +1,18 @@
+package org.dromara.common.core.exception.file;
+
+import java.io.Serial;
+
+/**
+ * 鏂囦欢鍚嶇О瓒呴暱闄愬埗寮傚父绫�
+ *
+ * @author ruoyi
+ */
+public class FileNameLengthLimitExceededException extends FileException {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    public FileNameLengthLimitExceededException(int defaultFileNameLength) {
+        super("upload.filename.exceed.length", new Object[]{defaultFileNameLength});
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileSizeLimitExceededException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileSizeLimitExceededException.java
new file mode 100644
index 0000000..1eb8d40
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileSizeLimitExceededException.java
@@ -0,0 +1,18 @@
+package org.dromara.common.core.exception.file;
+
+import java.io.Serial;
+
+/**
+ * 鏂囦欢鍚嶅ぇ灏忛檺鍒跺紓甯哥被
+ *
+ * @author ruoyi
+ */
+public class FileSizeLimitExceededException extends FileException {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    public FileSizeLimitExceededException(long defaultMaxSize) {
+        super("upload.exceed.maxSize", new Object[]{defaultMaxSize});
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/CaptchaException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/CaptchaException.java
new file mode 100644
index 0000000..43824e0
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/CaptchaException.java
@@ -0,0 +1,18 @@
+package org.dromara.common.core.exception.user;
+
+import java.io.Serial;
+
+/**
+ * 楠岃瘉鐮侀敊璇紓甯哥被
+ *
+ * @author ruoyi
+ */
+public class CaptchaException extends UserException {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    public CaptchaException() {
+        super("user.jcaptcha.error");
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/CaptchaExpireException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/CaptchaExpireException.java
new file mode 100644
index 0000000..f4b8cac
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/CaptchaExpireException.java
@@ -0,0 +1,18 @@
+package org.dromara.common.core.exception.user;
+
+import java.io.Serial;
+
+/**
+ * 楠岃瘉鐮佸け鏁堝紓甯哥被
+ *
+ * @author ruoyi
+ */
+public class CaptchaExpireException extends UserException {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    public CaptchaExpireException() {
+        super("user.jcaptcha.expire");
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserException.java
new file mode 100644
index 0000000..024fed6
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserException.java
@@ -0,0 +1,20 @@
+package org.dromara.common.core.exception.user;
+
+import org.dromara.common.core.exception.base.BaseException;
+
+import java.io.Serial;
+
+/**
+ * 鐢ㄦ埛淇℃伅寮傚父绫�
+ *
+ * @author ruoyi
+ */
+public class UserException extends BaseException {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    public UserException(String code, Object... args) {
+        super("user", code, args, null);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserPasswordNotMatchException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserPasswordNotMatchException.java
new file mode 100644
index 0000000..289cca7
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserPasswordNotMatchException.java
@@ -0,0 +1,18 @@
+package org.dromara.common.core.exception.user;
+
+import java.io.Serial;
+
+/**
+ * 鐢ㄦ埛瀵嗙爜涓嶆纭垨涓嶇鍚堣鑼冨紓甯哥被
+ *
+ * @author ruoyi
+ */
+public class UserPasswordNotMatchException extends UserException {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    public UserPasswordNotMatchException() {
+        super("user.password.not.match");
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserPasswordRetryLimitExceedException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserPasswordRetryLimitExceedException.java
new file mode 100644
index 0000000..2facdeb
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserPasswordRetryLimitExceedException.java
@@ -0,0 +1,19 @@
+package org.dromara.common.core.exception.user;
+
+import java.io.Serial;
+
+/**
+ * 鐢ㄦ埛閿欒鏈�澶ф鏁板紓甯哥被
+ *
+ * @author ruoyi
+ */
+public class UserPasswordRetryLimitExceedException extends UserException {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    public UserPasswordRetryLimitExceedException(int retryLimitCount, int lockTime) {
+        super("user.password.retry.limit.exceed", retryLimitCount, lockTime);
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/manager/ShutdownManager.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/manager/ShutdownManager.java
new file mode 100644
index 0000000..45ba7d3
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/manager/ShutdownManager.java
@@ -0,0 +1,41 @@
+package org.dromara.common.core.manager;
+
+import org.dromara.common.core.utils.Threads;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Component;
+
+import jakarta.annotation.PreDestroy;
+import java.util.concurrent.ScheduledExecutorService;
+
+/**
+ * 纭繚搴旂敤閫�鍑烘椂鑳藉叧闂悗鍙扮嚎绋�
+ *
+ * @author Lion Li
+ */
+@Slf4j
+@Component
+public class ShutdownManager {
+
+    @Autowired
+    @Qualifier("scheduledExecutorService")
+    private ScheduledExecutorService scheduledExecutorService;
+
+    @PreDestroy
+    public void destroy() {
+        shutdownAsyncManager();
+    }
+
+    /**
+     * 鍋滄寮傛鎵ц浠诲姟
+     */
+    private void shutdownAsyncManager() {
+        try {
+            log.info("====鍏抽棴鍚庡彴浠诲姟浠诲姟绾跨▼姹�====");
+            Threads.shutdownAndAwaitTermination(scheduledExecutorService);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/ConfigService.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/ConfigService.java
new file mode 100644
index 0000000..7328c69
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/ConfigService.java
@@ -0,0 +1,18 @@
+package org.dromara.common.core.service;
+
+/**
+ * 閫氱敤 鍙傛暟閰嶇疆鏈嶅姟
+ *
+ * @author Lion Li
+ */
+public interface ConfigService {
+
+    /**
+     * 鏍规嵁鍙傛暟 key 鑾峰彇鍙傛暟鍊�
+     *
+     * @param configKey 鍙傛暟 key
+     * @return 鍙傛暟鍊�
+     */
+    String getConfigValue(String configKey);
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/DeptService.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/DeptService.java
new file mode 100644
index 0000000..db9463e
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/DeptService.java
@@ -0,0 +1,18 @@
+package org.dromara.common.core.service;
+
+/**
+ * 閫氱敤 閮ㄩ棬鏈嶅姟
+ *
+ * @author Lion Li
+ */
+public interface DeptService {
+
+    /**
+     * 閫氳繃閮ㄩ棬ID鏌ヨ閮ㄩ棬鍚嶇О
+     *
+     * @param deptIds 閮ㄩ棬ID涓查�楀彿鍒嗛殧
+     * @return 閮ㄩ棬鍚嶇О涓查�楀彿鍒嗛殧
+     */
+    String selectDeptNameByIds(String deptIds);
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/DictService.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/DictService.java
new file mode 100644
index 0000000..04d0f9b
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/DictService.java
@@ -0,0 +1,57 @@
+package org.dromara.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/ruoyi-common-core/src/main/java/org/dromara/common/core/service/OssService.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/OssService.java
new file mode 100644
index 0000000..43742b3
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/OssService.java
@@ -0,0 +1,18 @@
+package org.dromara.common.core.service;
+
+/**
+ * 閫氱敤 OSS鏈嶅姟
+ *
+ * @author Lion Li
+ */
+public interface OssService {
+
+    /**
+     * 閫氳繃ossId鏌ヨ瀵瑰簲鐨剈rl
+     *
+     * @param ossIds ossId涓查�楀彿鍒嗛殧
+     * @return url涓查�楀彿鍒嗛殧
+     */
+    String selectUrlByIds(String ossIds);
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java
new file mode 100644
index 0000000..554e506
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java
@@ -0,0 +1,18 @@
+package org.dromara.common.core.service;
+
+/**
+ * 閫氱敤 鐢ㄦ埛鏈嶅姟
+ *
+ * @author Lion Li
+ */
+public interface UserService {
+
+    /**
+     * 閫氳繃鐢ㄦ埛ID鏌ヨ鐢ㄦ埛璐︽埛
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 鐢ㄦ埛璐︽埛
+     */
+    String selectUserNameById(Long userId);
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/DateUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/DateUtils.java
new file mode 100644
index 0000000..72178a7
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/DateUtils.java
@@ -0,0 +1,168 @@
+package org.dromara.common.core.utils;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.time.DateFormatUtils;
+
+import java.lang.management.ManagementFactory;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.util.Date;
+
+/**
+ * 鏃堕棿宸ュ叿绫�
+ *
+ * @author ruoyi
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
+
+    public static final String YYYY = "yyyy";
+
+    public static final String YYYY_MM = "yyyy-MM";
+
+    public static final String YYYY_MM_DD = "yyyy-MM-dd";
+
+    public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
+
+    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
+
+    private static final String[] PARSE_PATTERNS = {
+        "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
+        "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
+        "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
+
+    /**
+     * 鑾峰彇褰撳墠Date鍨嬫棩鏈�
+     *
+     * @return Date() 褰撳墠鏃ユ湡
+     */
+    public static Date getNowDate() {
+        return new Date();
+    }
+
+    /**
+     * 鑾峰彇褰撳墠鏃ユ湡, 榛樿鏍煎紡涓簓yyy-MM-dd
+     *
+     * @return String
+     */
+    public static String getDate() {
+        return dateTimeNow(YYYY_MM_DD);
+    }
+
+    public static String getTime() {
+        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
+    }
+
+    public static String dateTimeNow() {
+        return dateTimeNow(YYYYMMDDHHMMSS);
+    }
+
+    public static String dateTimeNow(final String format) {
+        return parseDateToStr(format, new Date());
+    }
+
+    public static String dateTime(final Date date) {
+        return parseDateToStr(YYYY_MM_DD, date);
+    }
+
+    public static String parseDateToStr(final String format, final Date date) {
+        return new SimpleDateFormat(format).format(date);
+    }
+
+    public static Date dateTime(final String format, final String ts) {
+        try {
+            return new SimpleDateFormat(format).parse(ts);
+        } catch (ParseException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * 鏃ユ湡璺緞 鍗冲勾/鏈�/鏃� 濡�2018/08/08
+     */
+    public static String datePath() {
+        Date now = new Date();
+        return DateFormatUtils.format(now, "yyyy/MM/dd");
+    }
+
+    /**
+     * 鏃ユ湡璺緞 鍗冲勾/鏈�/鏃� 濡�20180808
+     */
+    public static String dateTime() {
+        Date now = new Date();
+        return DateFormatUtils.format(now, "yyyyMMdd");
+    }
+
+    /**
+     * 鏃ユ湡鍨嬪瓧绗︿覆杞寲涓烘棩鏈� 鏍煎紡
+     */
+    public static Date parseDate(Object str) {
+        if (str == null) {
+            return null;
+        }
+        try {
+            return parseDate(str.toString(), PARSE_PATTERNS);
+        } catch (ParseException e) {
+            return null;
+        }
+    }
+
+    /**
+     * 鑾峰彇鏈嶅姟鍣ㄥ惎鍔ㄦ椂闂�
+     */
+    public static Date getServerStartDate() {
+        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
+        return new Date(time);
+    }
+
+    /**
+     * 璁$畻鐩稿樊澶╂暟
+     */
+    public static int differentDaysByMillisecond(Date date1, Date date2) {
+        return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
+    }
+
+    /**
+     * 璁$畻涓や釜鏃堕棿宸�
+     */
+    public static String getDatePoor(Date endDate, Date nowDate) {
+        long nd = 1000 * 24 * 60 * 60;
+        long nh = 1000 * 60 * 60;
+        long nm = 1000 * 60;
+        // long ns = 1000;
+        // 鑾峰緱涓や釜鏃堕棿鐨勬绉掓椂闂村樊寮�
+        long diff = endDate.getTime() - nowDate.getTime();
+        // 璁$畻宸灏戝ぉ
+        long day = diff / nd;
+        // 璁$畻宸灏戝皬鏃�
+        long hour = diff % nd / nh;
+        // 璁$畻宸灏戝垎閽�
+        long min = diff % nd % nh / nm;
+        // 璁$畻宸灏戠//杈撳嚭缁撴灉
+        // long sec = diff % nd % nh % nm / ns;
+        return day + "澶�" + hour + "灏忔椂" + min + "鍒嗛挓";
+    }
+
+    /**
+     * 澧炲姞 LocalDateTime ==> Date
+     */
+    public static Date toDate(LocalDateTime temporalAccessor) {
+        ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
+        return Date.from(zdt.toInstant());
+    }
+
+    /**
+     * 澧炲姞 LocalDate ==> Date
+     */
+    public static Date toDate(LocalDate temporalAccessor) {
+        LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
+        ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
+        return Date.from(zdt.toInstant());
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/MapstructUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/MapstructUtils.java
new file mode 100644
index 0000000..a57c1ea
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/MapstructUtils.java
@@ -0,0 +1,92 @@
+package org.dromara.common.core.utils;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.util.ObjectUtil;
+import io.github.linpeilie.Converter;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Mapstruct 宸ュ叿绫�
+ * <p>鍙傝�冩枃妗o細<a href="https://mapstruct.plus/guide/quick-start">mapstruct-plus</a></p>
+ *
+ * @author Michelle.Chung
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class MapstructUtils {
+
+    private final static Converter CONVERTER = SpringUtils.getBean(Converter.class);
+
+    /**
+     * 灏� T 绫诲瀷瀵硅薄锛岃浆鎹负 desc 绫诲瀷鐨勫璞″苟杩斿洖
+     *
+     * @param source 鏁版嵁鏉ユ簮瀹炰綋
+     * @param desc   鎻忚堪瀵硅薄 杞崲鍚庣殑瀵硅薄
+     * @return desc
+     */
+    public static <T, V> V convert(T source, Class<V> desc) {
+        if (ObjectUtil.isNull(source)) {
+            return null;
+        }
+        if (ObjectUtil.isNull(desc)) {
+            return null;
+        }
+        return CONVERTER.convert(source, desc);
+    }
+
+    /**
+     * 灏� T 绫诲瀷瀵硅薄锛屾寜鐓ч厤缃殑鏄犲皠瀛楁瑙勫垯锛岀粰 desc 绫诲瀷鐨勫璞¤祴鍊煎苟杩斿洖 desc 瀵硅薄
+     *
+     * @param source 鏁版嵁鏉ユ簮瀹炰綋
+     * @param desc   杞崲鍚庣殑瀵硅薄
+     * @return desc
+     */
+    public static <T, V> V convert(T source, V desc) {
+        if (ObjectUtil.isNull(source)) {
+            return null;
+        }
+        if (ObjectUtil.isNull(desc)) {
+            return null;
+        }
+        return CONVERTER.convert(source, desc);
+    }
+
+    /**
+     * 灏� T 绫诲瀷鐨勯泦鍚堬紝杞崲涓� desc 绫诲瀷鐨勯泦鍚堝苟杩斿洖
+     *
+     * @param sourceList 鏁版嵁鏉ユ簮瀹炰綋鍒楄〃
+     * @param desc       鎻忚堪瀵硅薄 杞崲鍚庣殑瀵硅薄
+     * @return desc
+     */
+    public static <T, V> List<V> convert(List<T> sourceList, Class<V> desc) {
+        if (ObjectUtil.isNull(sourceList)) {
+            return null;
+        }
+        if (CollUtil.isEmpty(sourceList)) {
+            return CollUtil.newArrayList();
+        }
+        return CONVERTER.convert(sourceList, desc);
+    }
+
+    /**
+     * 灏� Map 杞崲涓� beanClass 绫诲瀷鐨勯泦鍚堝苟杩斿洖
+     *
+     * @param map       鏁版嵁鏉ユ簮
+     * @param beanClass bean绫�
+     * @return bean瀵硅薄
+     */
+    public static <T> T convert(Map<String, Object> map, Class<T> beanClass) {
+        if (MapUtil.isEmpty(map)) {
+            return null;
+        }
+        if (ObjectUtil.isNull(beanClass)) {
+            return null;
+        }
+        return CONVERTER.convert(map, beanClass);
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/MessageUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/MessageUtils.java
new file mode 100644
index 0000000..6f3729b
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/MessageUtils.java
@@ -0,0 +1,28 @@
+package org.dromara.common.core.utils;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.springframework.context.MessageSource;
+import org.springframework.context.i18n.LocaleContextHolder;
+
+/**
+ * 鑾峰彇i18n璧勬簮鏂囦欢
+ *
+ * @author Lion Li
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class MessageUtils {
+
+    private static final MessageSource MESSAGE_SOURCE = SpringUtils.getBean(MessageSource.class);
+
+    /**
+     * 鏍规嵁娑堟伅閿拰鍙傛暟 鑾峰彇娑堟伅 濮旀墭缁檚pring messageSource
+     *
+     * @param code 娑堟伅閿�
+     * @param args 鍙傛暟
+     * @return 鑾峰彇鍥介檯鍖栫炕璇戝��
+     */
+    public static String message(String code, Object... args) {
+        return MESSAGE_SOURCE.getMessage(code, args, LocaleContextHolder.getLocale());
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ServletUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ServletUtils.java
new file mode 100644
index 0000000..91e2990
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ServletUtils.java
@@ -0,0 +1,193 @@
+package org.dromara.common.core.utils;
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.extra.servlet.JakartaServletUtil;
+import cn.hutool.http.HttpStatus;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpSession;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.springframework.http.MediaType;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import java.io.IOException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 瀹㈡埛绔伐鍏风被
+ *
+ * @author ruoyi
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class ServletUtils extends JakartaServletUtil {
+
+    /**
+     * 鑾峰彇String鍙傛暟
+     */
+    public static String getParameter(String name) {
+        return getRequest().getParameter(name);
+    }
+
+    /**
+     * 鑾峰彇String鍙傛暟
+     */
+    public static String getParameter(String name, String defaultValue) {
+        return Convert.toStr(getRequest().getParameter(name), defaultValue);
+    }
+
+    /**
+     * 鑾峰彇Integer鍙傛暟
+     */
+    public static Integer getParameterToInt(String name) {
+        return Convert.toInt(getRequest().getParameter(name));
+    }
+
+    /**
+     * 鑾峰彇Integer鍙傛暟
+     */
+    public static Integer getParameterToInt(String name, Integer defaultValue) {
+        return Convert.toInt(getRequest().getParameter(name), defaultValue);
+    }
+
+    /**
+     * 鑾峰彇Boolean鍙傛暟
+     */
+    public static Boolean getParameterToBool(String name) {
+        return Convert.toBool(getRequest().getParameter(name));
+    }
+
+    /**
+     * 鑾峰彇Boolean鍙傛暟
+     */
+    public static Boolean getParameterToBool(String name, Boolean defaultValue) {
+        return Convert.toBool(getRequest().getParameter(name), defaultValue);
+    }
+
+    /**
+     * 鑾峰緱鎵�鏈夎姹傚弬鏁�
+     *
+     * @param request 璇锋眰瀵硅薄{@link ServletRequest}
+     * @return Map
+     */
+    public static Map<String, String[]> getParams(ServletRequest request) {
+        final Map<String, String[]> map = request.getParameterMap();
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * 鑾峰緱鎵�鏈夎姹傚弬鏁�
+     *
+     * @param request 璇锋眰瀵硅薄{@link ServletRequest}
+     * @return Map
+     */
+    public static Map<String, String> getParamMap(ServletRequest request) {
+        Map<String, String> params = new HashMap<>();
+        for (Map.Entry<String, String[]> entry : getParams(request).entrySet()) {
+            params.put(entry.getKey(), StringUtils.join(entry.getValue(), StringUtils.SEPARATOR));
+        }
+        return params;
+    }
+
+    /**
+     * 鑾峰彇request
+     */
+    public static HttpServletRequest getRequest() {
+        return getRequestAttributes().getRequest();
+    }
+
+    /**
+     * 鑾峰彇response
+     */
+    public static HttpServletResponse getResponse() {
+        return getRequestAttributes().getResponse();
+    }
+
+    /**
+     * 鑾峰彇session
+     */
+    public static HttpSession getSession() {
+        return getRequest().getSession();
+    }
+
+    public static ServletRequestAttributes getRequestAttributes() {
+        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
+        return (ServletRequestAttributes) attributes;
+    }
+
+    /**
+     * 灏嗗瓧绗︿覆娓叉煋鍒板鎴风
+     *
+     * @param response 娓叉煋瀵硅薄
+     * @param string   寰呮覆鏌撶殑瀛楃涓�
+     */
+    public static void renderString(HttpServletResponse response, String string) {
+        try {
+            response.setStatus(HttpStatus.HTTP_OK);
+            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
+            response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
+            response.getWriter().print(string);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 鏄惁鏄疉jax寮傛璇锋眰
+     *
+     * @param request
+     */
+    public static boolean isAjaxRequest(HttpServletRequest request) {
+
+        String accept = request.getHeader("accept");
+        if (accept != null && accept.contains(MediaType.APPLICATION_JSON_VALUE)) {
+            return true;
+        }
+
+        String xRequestedWith = request.getHeader("X-Requested-With");
+        if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) {
+            return true;
+        }
+
+        String uri = request.getRequestURI();
+        if (StringUtils.equalsAnyIgnoreCase(uri, ".json", ".xml")) {
+            return true;
+        }
+
+        String ajax = request.getParameter("__ajax");
+        return StringUtils.equalsAnyIgnoreCase(ajax, "json", "xml");
+    }
+
+    public static String getClientIP() {
+        return getClientIP(getRequest());
+    }
+
+    /**
+     * 鍐呭缂栫爜
+     *
+     * @param str 鍐呭
+     * @return 缂栫爜鍚庣殑鍐呭
+     */
+    public static String urlEncode(String str) {
+        return URLEncoder.encode(str, StandardCharsets.UTF_8);
+    }
+
+    /**
+     * 鍐呭瑙g爜
+     *
+     * @param str 鍐呭
+     * @return 瑙g爜鍚庣殑鍐呭
+     */
+    public static String urlDecode(String str) {
+        return URLDecoder.decode(str, StandardCharsets.UTF_8);
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/SpringUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/SpringUtils.java
new file mode 100644
index 0000000..ab50539
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/SpringUtils.java
@@ -0,0 +1,62 @@
+package org.dromara.common.core.utils;
+
+import cn.hutool.extra.spring.SpringUtil;
+import org.springframework.aop.framework.AopContext;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Component;
+
+/**
+ * spring宸ュ叿绫�
+ *
+ * @author Lion Li
+ */
+@Component
+public final class SpringUtils extends SpringUtil {
+
+    /**
+     * 濡傛灉BeanFactory鍖呭惈涓�涓笌鎵�缁欏悕绉板尮閰嶇殑bean瀹氫箟锛屽垯杩斿洖true
+     */
+    public static boolean containsBean(String name) {
+        return getBeanFactory().containsBean(name);
+    }
+
+    /**
+     * 鍒ゆ柇浠ョ粰瀹氬悕瀛楁敞鍐岀殑bean瀹氫箟鏄竴涓猻ingleton杩樻槸涓�涓猵rototype銆�
+     * 濡傛灉涓庣粰瀹氬悕瀛楃浉搴旂殑bean瀹氫箟娌℃湁琚壘鍒帮紝灏嗕細鎶涘嚭涓�涓紓甯革紙NoSuchBeanDefinitionException锛�
+     */
+    public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
+        return getBeanFactory().isSingleton(name);
+    }
+
+    /**
+     * @return Class 娉ㄥ唽瀵硅薄鐨勭被鍨�
+     */
+    public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
+        return getBeanFactory().getType(name);
+    }
+
+    /**
+     * 濡傛灉缁欏畾鐨刡ean鍚嶅瓧鍦╞ean瀹氫箟涓湁鍒悕锛屽垯杩斿洖杩欎簺鍒悕
+     */
+    public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
+        return getBeanFactory().getAliases(name);
+    }
+
+    /**
+     * 鑾峰彇aop浠g悊瀵硅薄
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T getAopProxy(T invoker) {
+        return (T) AopContext.currentProxy();
+    }
+
+
+    /**
+     * 鑾峰彇spring涓婁笅鏂�
+     */
+    public static ApplicationContext context() {
+        return getApplicationContext();
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/StreamUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/StreamUtils.java
new file mode 100644
index 0000000..d9dcb40
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/StreamUtils.java
@@ -0,0 +1,254 @@
+package org.dromara.common.core.utils;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.map.MapUtil;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import java.util.*;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * stream 娴佸伐鍏风被
+ *
+ * @author Lion Li
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class StreamUtils {
+
+    /**
+     * 灏哻ollection杩囨护
+     *
+     * @param collection 闇�瑕佽浆鍖栫殑闆嗗悎
+     * @param function   杩囨护鏂规硶
+     * @return 杩囨护鍚庣殑list
+     */
+    public static <E> List<E> filter(Collection<E> collection, Predicate<E> function) {
+        if (CollUtil.isEmpty(collection)) {
+            return CollUtil.newArrayList();
+        }
+        // 娉ㄦ剰姝ゅ涓嶈浣跨敤 .toList() 鏂拌娉� 鍥犱负杩斿洖鐨勬槸涓嶅彲鍙楲ist 浼氬鑷村簭鍒楀寲闂
+        return collection.stream().filter(function).collect(Collectors.toList());
+    }
+
+    /**
+     * 灏哻ollection鎷兼帴
+     *
+     * @param collection 闇�瑕佽浆鍖栫殑闆嗗悎
+     * @param function   鎷兼帴鏂规硶
+     * @return 鎷兼帴鍚庣殑list
+     */
+    public static <E> String join(Collection<E> collection, Function<E, String> function) {
+        return join(collection, function, StringUtils.SEPARATOR);
+    }
+
+    /**
+     * 灏哻ollection鎷兼帴
+     *
+     * @param collection 闇�瑕佽浆鍖栫殑闆嗗悎
+     * @param function   鎷兼帴鏂规硶
+     * @param delimiter  鎷兼帴绗�
+     * @return 鎷兼帴鍚庣殑list
+     */
+    public static <E> String join(Collection<E> collection, Function<E, String> function, CharSequence delimiter) {
+        if (CollUtil.isEmpty(collection)) {
+            return StringUtils.EMPTY;
+        }
+        return collection.stream().map(function).filter(Objects::nonNull).collect(Collectors.joining(delimiter));
+    }
+
+    /**
+     * 灏哻ollection鎺掑簭
+     *
+     * @param collection 闇�瑕佽浆鍖栫殑闆嗗悎
+     * @param comparing  鎺掑簭鏂规硶
+     * @return 鎺掑簭鍚庣殑list
+     */
+    public static <E> List<E> sorted(Collection<E> collection, Comparator<E> comparing) {
+        if (CollUtil.isEmpty(collection)) {
+            return CollUtil.newArrayList();
+        }
+        // 娉ㄦ剰姝ゅ涓嶈浣跨敤 .toList() 鏂拌娉� 鍥犱负杩斿洖鐨勬槸涓嶅彲鍙楲ist 浼氬鑷村簭鍒楀寲闂
+        return collection.stream().sorted(comparing).collect(Collectors.toList());
+    }
+
+    /**
+     * 灏哻ollection杞寲涓虹被鍨嬩笉鍙樼殑map<br>
+     * <B>{@code Collection<V>  ---->  Map<K,V>}</B>
+     *
+     * @param collection 闇�瑕佽浆鍖栫殑闆嗗悎
+     * @param key        V绫诲瀷杞寲涓篕绫诲瀷鐨刲ambda鏂规硶
+     * @param <V>        collection涓殑娉涘瀷
+     * @param <K>        map涓殑key绫诲瀷
+     * @return 杞寲鍚庣殑map
+     */
+    public static <V, K> Map<K, V> toIdentityMap(Collection<V> collection, Function<V, K> key) {
+        if (CollUtil.isEmpty(collection)) {
+            return MapUtil.newHashMap();
+        }
+        return collection.stream().collect(Collectors.toMap(key, Function.identity(), (l, r) -> l));
+    }
+
+    /**
+     * 灏咰ollection杞寲涓簃ap(value绫诲瀷涓巆ollection鐨勬硾鍨嬩笉鍚�)<br>
+     * <B>{@code Collection<E> -----> Map<K,V>  }</B>
+     *
+     * @param collection 闇�瑕佽浆鍖栫殑闆嗗悎
+     * @param key        E绫诲瀷杞寲涓篕绫诲瀷鐨刲ambda鏂规硶
+     * @param value      E绫诲瀷杞寲涓篤绫诲瀷鐨刲ambda鏂规硶
+     * @param <E>        collection涓殑娉涘瀷
+     * @param <K>        map涓殑key绫诲瀷
+     * @param <V>        map涓殑value绫诲瀷
+     * @return 杞寲鍚庣殑map
+     */
+    public static <E, K, V> Map<K, V> toMap(Collection<E> collection, Function<E, K> key, Function<E, V> value) {
+        if (CollUtil.isEmpty(collection)) {
+            return MapUtil.newHashMap();
+        }
+        return collection.stream().collect(Collectors.toMap(key, value, (l, r) -> l));
+    }
+
+    /**
+     * 灏哻ollection鎸夌収瑙勫垯(姣斿鏈夌浉鍚岀殑鐝骇id)鍒嗙被鎴恗ap<br>
+     * <B>{@code Collection<E> -------> Map<K,List<E>> } </B>
+     *
+     * @param collection 闇�瑕佸垎绫荤殑闆嗗悎
+     * @param key        鍒嗙被鐨勮鍒�
+     * @param <E>        collection涓殑娉涘瀷
+     * @param <K>        map涓殑key绫诲瀷
+     * @return 鍒嗙被鍚庣殑map
+     */
+    public static <E, K> Map<K, List<E>> groupByKey(Collection<E> collection, Function<E, K> key) {
+        if (CollUtil.isEmpty(collection)) {
+            return MapUtil.newHashMap();
+        }
+        return collection
+            .stream()
+            .collect(Collectors.groupingBy(key, LinkedHashMap::new, Collectors.toList()));
+    }
+
+    /**
+     * 灏哻ollection鎸夌収涓や釜瑙勫垯(姣斿鏈夌浉鍚岀殑骞寸骇id,鐝骇id)鍒嗙被鎴愬弻灞俶ap<br>
+     * <B>{@code Collection<E>  --->  Map<T,Map<U,List<E>>> } </B>
+     *
+     * @param collection 闇�瑕佸垎绫荤殑闆嗗悎
+     * @param key1       绗竴涓垎绫荤殑瑙勫垯
+     * @param key2       绗簩涓垎绫荤殑瑙勫垯
+     * @param <E>        闆嗗悎鍏冪礌绫诲瀷
+     * @param <K>        绗竴涓猰ap涓殑key绫诲瀷
+     * @param <U>        绗簩涓猰ap涓殑key绫诲瀷
+     * @return 鍒嗙被鍚庣殑map
+     */
+    public static <E, K, U> Map<K, Map<U, List<E>>> groupBy2Key(Collection<E> collection, Function<E, K> key1, Function<E, U> key2) {
+        if (CollUtil.isEmpty(collection)) {
+            return MapUtil.newHashMap();
+        }
+        return collection
+            .stream()
+            .collect(Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.groupingBy(key2, LinkedHashMap::new, Collectors.toList())));
+    }
+
+    /**
+     * 灏哻ollection鎸夌収涓や釜瑙勫垯(姣斿鏈夌浉鍚岀殑骞寸骇id,鐝骇id)鍒嗙被鎴愬弻灞俶ap<br>
+     * <B>{@code Collection<E>  --->  Map<T,Map<U,E>> } </B>
+     *
+     * @param collection 闇�瑕佸垎绫荤殑闆嗗悎
+     * @param key1       绗竴涓垎绫荤殑瑙勫垯
+     * @param key2       绗簩涓垎绫荤殑瑙勫垯
+     * @param <T>        绗竴涓猰ap涓殑key绫诲瀷
+     * @param <U>        绗簩涓猰ap涓殑key绫诲瀷
+     * @param <E>        collection涓殑娉涘瀷
+     * @return 鍒嗙被鍚庣殑map
+     */
+    public static <E, T, U> Map<T, Map<U, E>> group2Map(Collection<E> collection, Function<E, T> key1, Function<E, U> key2) {
+        if (CollUtil.isEmpty(collection) || key1 == null || key2 == null) {
+            return MapUtil.newHashMap();
+        }
+        return collection
+            .stream()
+            .collect(Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.toMap(key2, Function.identity(), (l, r) -> l)));
+    }
+
+    /**
+     * 灏哻ollection杞寲涓篖ist闆嗗悎锛屼絾鏄袱鑰呯殑娉涘瀷涓嶅悓<br>
+     * <B>{@code Collection<E>  ------>  List<T> } </B>
+     *
+     * @param collection 闇�瑕佽浆鍖栫殑闆嗗悎
+     * @param function   collection涓殑娉涘瀷杞寲涓簂ist娉涘瀷鐨刲ambda琛ㄨ揪寮�
+     * @param <E>        collection涓殑娉涘瀷
+     * @param <T>        List涓殑娉涘瀷
+     * @return 杞寲鍚庣殑list
+     */
+    public static <E, T> List<T> toList(Collection<E> collection, Function<E, T> function) {
+        if (CollUtil.isEmpty(collection)) {
+            return CollUtil.newArrayList();
+        }
+        return collection
+            .stream()
+            .map(function)
+            .filter(Objects::nonNull)
+            // 娉ㄦ剰姝ゅ涓嶈浣跨敤 .toList() 鏂拌娉� 鍥犱负杩斿洖鐨勬槸涓嶅彲鍙楲ist 浼氬鑷村簭鍒楀寲闂
+            .collect(Collectors.toList());
+    }
+
+    /**
+     * 灏哻ollection杞寲涓篠et闆嗗悎锛屼絾鏄袱鑰呯殑娉涘瀷涓嶅悓<br>
+     * <B>{@code Collection<E>  ------>  Set<T> } </B>
+     *
+     * @param collection 闇�瑕佽浆鍖栫殑闆嗗悎
+     * @param function   collection涓殑娉涘瀷杞寲涓簊et娉涘瀷鐨刲ambda琛ㄨ揪寮�
+     * @param <E>        collection涓殑娉涘瀷
+     * @param <T>        Set涓殑娉涘瀷
+     * @return 杞寲鍚庣殑Set
+     */
+    public static <E, T> Set<T> toSet(Collection<E> collection, Function<E, T> function) {
+        if (CollUtil.isEmpty(collection) || function == null) {
+            return CollUtil.newHashSet();
+        }
+        return collection
+            .stream()
+            .map(function)
+            .filter(Objects::nonNull)
+            .collect(Collectors.toSet());
+    }
+
+
+    /**
+     * 鍚堝苟涓や釜鐩稿悓key绫诲瀷鐨刴ap
+     *
+     * @param map1  绗竴涓渶瑕佸悎骞剁殑 map
+     * @param map2  绗簩涓渶瑕佸悎骞剁殑 map
+     * @param merge 鍚堝苟鐨刲ambda锛屽皢key  value1 value2鍚堝苟鎴愭渶缁堢殑绫诲瀷,娉ㄦ剰value鍙兘涓虹┖鐨勬儏鍐�
+     * @param <K>   map涓殑key绫诲瀷
+     * @param <X>   绗竴涓� map鐨剉alue绫诲瀷
+     * @param <Y>   绗簩涓� map鐨剉alue绫诲瀷
+     * @param <V>   鏈�缁坢ap鐨剉alue绫诲瀷
+     * @return 鍚堝苟鍚庣殑map
+     */
+    public static <K, X, Y, V> Map<K, V> merge(Map<K, X> map1, Map<K, Y> map2, BiFunction<X, Y, V> merge) {
+        if (MapUtil.isEmpty(map1) && MapUtil.isEmpty(map2)) {
+            return MapUtil.newHashMap();
+        } else if (MapUtil.isEmpty(map1)) {
+            map1 = MapUtil.newHashMap();
+        } else if (MapUtil.isEmpty(map2)) {
+            map2 = MapUtil.newHashMap();
+        }
+        Set<K> key = new HashSet<>();
+        key.addAll(map1.keySet());
+        key.addAll(map2.keySet());
+        Map<K, V> map = new HashMap<>();
+        for (K t : key) {
+            X x = map1.get(t);
+            Y y = map2.get(t);
+            V z = merge.apply(x, y);
+            if (z != null) {
+                map.put(t, z);
+            }
+        }
+        return map;
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/StringUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/StringUtils.java
new file mode 100644
index 0000000..5e4db50
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/StringUtils.java
@@ -0,0 +1,321 @@
+package org.dromara.common.core.utils;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.lang.Validator;
+import cn.hutool.core.util.StrUtil;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.springframework.util.AntPathMatcher;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * 瀛楃涓插伐鍏风被
+ *
+ * @author Lion Li
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class StringUtils extends org.apache.commons.lang3.StringUtils {
+
+    public static final String SEPARATOR = ",";
+
+    /**
+     * 鑾峰彇鍙傛暟涓嶄负绌哄��
+     *
+     * @param str defaultValue 瑕佸垽鏂殑value
+     * @return value 杩斿洖鍊�
+     */
+    public static String blankToDefault(String str, String defaultValue) {
+        return StrUtil.blankToDefault(str, defaultValue);
+    }
+
+    /**
+     * * 鍒ゆ柇涓�涓瓧绗︿覆鏄惁涓虹┖涓�
+     *
+     * @param str String
+     * @return true锛氫负绌� false锛氶潪绌�
+     */
+    public static boolean isEmpty(String str) {
+        return StrUtil.isEmpty(str);
+    }
+
+    /**
+     * * 鍒ゆ柇涓�涓瓧绗︿覆鏄惁涓洪潪绌轰覆
+     *
+     * @param str String
+     * @return true锛氶潪绌轰覆 false锛氱┖涓�
+     */
+    public static boolean isNotEmpty(String str) {
+        return !isEmpty(str);
+    }
+
+    /**
+     * 鍘荤┖鏍�
+     */
+    public static String trim(String str) {
+        return StrUtil.trim(str);
+    }
+
+    /**
+     * 鎴彇瀛楃涓�
+     *
+     * @param str   瀛楃涓�
+     * @param start 寮�濮�
+     * @return 缁撴灉
+     */
+    public static String substring(final String str, int start) {
+        return substring(str, start, str.length());
+    }
+
+    /**
+     * 鎴彇瀛楃涓�
+     *
+     * @param str   瀛楃涓�
+     * @param start 寮�濮�
+     * @param end   缁撴潫
+     * @return 缁撴灉
+     */
+    public static String substring(final String str, int start, int end) {
+        return StrUtil.sub(str, start, end);
+    }
+
+    /**
+     * 鏍煎紡鍖栨枃鏈�, {} 琛ㄧず鍗犱綅绗�<br>
+     * 姝ゆ柟娉曞彧鏄畝鍗曞皢鍗犱綅绗� {} 鎸夌収椤哄簭鏇挎崲涓哄弬鏁�<br>
+     * 濡傛灉鎯宠緭鍑� {} 浣跨敤 \\杞箟 { 鍗冲彲锛屽鏋滄兂杈撳嚭 {} 涔嬪墠鐨� \ 浣跨敤鍙岃浆涔夌 \\\\ 鍗冲彲<br>
+     * 渚嬶細<br>
+     * 閫氬父浣跨敤锛歠ormat("this is {} for {}", "a", "b") -> this is a for b<br>
+     * 杞箟{}锛� format("this is \\{} for {}", "a", "b") -> this is {} for a<br>
+     * 杞箟\锛� format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
+     *
+     * @param template 鏂囨湰妯℃澘锛岃鏇挎崲鐨勯儴鍒嗙敤 {} 琛ㄧず
+     * @param params   鍙傛暟鍊�
+     * @return 鏍煎紡鍖栧悗鐨勬枃鏈�
+     */
+    public static String format(String template, Object... params) {
+        return StrUtil.format(template, params);
+    }
+
+    /**
+     * 鏄惁涓篽ttp(s)://寮�澶�
+     *
+     * @param link 閾炬帴
+     * @return 缁撴灉
+     */
+    public static boolean ishttp(String link) {
+        return Validator.isUrl(link);
+    }
+
+    /**
+     * 瀛楃涓茶浆set
+     *
+     * @param str 瀛楃涓�
+     * @param sep 鍒嗛殧绗�
+     * @return set闆嗗悎
+     */
+    public static Set<String> str2Set(String str, String sep) {
+        return new HashSet<>(str2List(str, sep, true, false));
+    }
+
+    /**
+     * 瀛楃涓茶浆list
+     *
+     * @param str         瀛楃涓�
+     * @param sep         鍒嗛殧绗�
+     * @param filterBlank 杩囨护绾┖鐧�
+     * @param trim        鍘绘帀棣栧熬绌虹櫧
+     * @return list闆嗗悎
+     */
+    public static List<String> str2List(String str, String sep, boolean filterBlank, boolean trim) {
+        List<String> list = new ArrayList<>();
+        if (isEmpty(str)) {
+            return list;
+        }
+
+        // 杩囨护绌虹櫧瀛楃涓�
+        if (filterBlank && isBlank(str)) {
+            return list;
+        }
+        String[] split = str.split(sep);
+        for (String string : split) {
+            if (filterBlank && isBlank(string)) {
+                continue;
+            }
+            if (trim) {
+                string = trim(string);
+            }
+            list.add(string);
+        }
+
+        return list;
+    }
+
+    /**
+     * 鏌ユ壘鎸囧畾瀛楃涓叉槸鍚﹀寘鍚寚瀹氬瓧绗︿覆鍒楄〃涓殑浠绘剰涓�涓瓧绗︿覆鍚屾椂涓插拷鐣ュぇ灏忓啓
+     *
+     * @param cs                  鎸囧畾瀛楃涓�
+     * @param searchCharSequences 闇�瑕佹鏌ョ殑瀛楃涓叉暟缁�
+     * @return 鏄惁鍖呭惈浠绘剰涓�涓瓧绗︿覆
+     */
+    public static boolean containsAnyIgnoreCase(CharSequence cs, CharSequence... searchCharSequences) {
+        return StrUtil.containsAnyIgnoreCase(cs, searchCharSequences);
+    }
+
+    /**
+     * 椹煎嘲杞笅鍒掔嚎鍛藉悕
+     */
+    public static String toUnderScoreCase(String str) {
+        return StrUtil.toUnderlineCase(str);
+    }
+
+    /**
+     * 鏄惁鍖呭惈瀛楃涓�
+     *
+     * @param str  楠岃瘉瀛楃涓�
+     * @param strs 瀛楃涓茬粍
+     * @return 鍖呭惈杩斿洖true
+     */
+    public static boolean inStringIgnoreCase(String str, String... strs) {
+        return StrUtil.equalsAnyIgnoreCase(str, strs);
+    }
+
+    /**
+     * 灏嗕笅鍒掔嚎澶у啓鏂瑰紡鍛藉悕鐨勫瓧绗︿覆杞崲涓洪┘宄板紡銆傚鏋滆浆鎹㈠墠鐨勪笅鍒掔嚎澶у啓鏂瑰紡鍛藉悕鐨勫瓧绗︿覆涓虹┖锛屽垯杩斿洖绌哄瓧绗︿覆銆� 渚嬪锛欻ELLO_WORLD->HelloWorld
+     *
+     * @param name 杞崲鍓嶇殑涓嬪垝绾垮ぇ鍐欐柟寮忓懡鍚嶇殑瀛楃涓�
+     * @return 杞崲鍚庣殑椹煎嘲寮忓懡鍚嶇殑瀛楃涓�
+     */
+    public static String convertToCamelCase(String name) {
+        return StrUtil.upperFirst(StrUtil.toCamelCase(name));
+    }
+
+    /**
+     * 椹煎嘲寮忓懡鍚嶆硶 渚嬪锛歶ser_name->userName
+     */
+    public static String toCamelCase(String s) {
+        return StrUtil.toCamelCase(s);
+    }
+
+    /**
+     * 鏌ユ壘鎸囧畾瀛楃涓叉槸鍚﹀尮閰嶆寚瀹氬瓧绗︿覆鍒楄〃涓殑浠绘剰涓�涓瓧绗︿覆
+     *
+     * @param str  鎸囧畾瀛楃涓�
+     * @param strs 闇�瑕佹鏌ョ殑瀛楃涓叉暟缁�
+     * @return 鏄惁鍖归厤
+     */
+    public static boolean matches(String str, List<String> strs) {
+        if (isEmpty(str) || CollUtil.isEmpty(strs)) {
+            return false;
+        }
+        for (String pattern : strs) {
+            if (isMatch(pattern, str)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 鍒ゆ柇url鏄惁涓庤鍒欓厤缃�:
+     * ? 琛ㄧず鍗曚釜瀛楃;
+     * * 琛ㄧず涓�灞傝矾寰勫唴鐨勪换鎰忓瓧绗︿覆锛屼笉鍙法灞傜骇;
+     * ** 琛ㄧず浠绘剰灞傝矾寰�;
+     *
+     * @param pattern 鍖归厤瑙勫垯
+     * @param url     闇�瑕佸尮閰嶇殑url
+     */
+    public static boolean isMatch(String pattern, String url) {
+        AntPathMatcher matcher = new AntPathMatcher();
+        return matcher.match(pattern, url);
+    }
+
+    /**
+     * 鏁板瓧宸﹁竟琛ラ綈0锛屼娇涔嬭揪鍒版寚瀹氶暱搴︺�傛敞鎰忥紝濡傛灉鏁板瓧杞崲涓哄瓧绗︿覆鍚庯紝闀垮害澶т簬size锛屽垯鍙繚鐣� 鏈�鍚巗ize涓瓧绗︺��
+     *
+     * @param num  鏁板瓧瀵硅薄
+     * @param size 瀛楃涓叉寚瀹氶暱搴�
+     * @return 杩斿洖鏁板瓧鐨勫瓧绗︿覆鏍煎紡锛岃瀛楃涓蹭负鎸囧畾闀垮害銆�
+     */
+    public static String padl(final Number num, final int size) {
+        return padl(num.toString(), size, '0');
+    }
+
+    /**
+     * 瀛楃涓插乏琛ラ綈銆傚鏋滃師濮嬪瓧绗︿覆s闀垮害澶т簬size锛屽垯鍙繚鐣欐渶鍚巗ize涓瓧绗︺��
+     *
+     * @param s    鍘熷瀛楃涓�
+     * @param size 瀛楃涓叉寚瀹氶暱搴�
+     * @param c    鐢ㄤ簬琛ラ綈鐨勫瓧绗�
+     * @return 杩斿洖鎸囧畾闀垮害鐨勫瓧绗︿覆锛岀敱鍘熷瓧绗︿覆宸﹁ˉ榻愭垨鎴彇寰楀埌銆�
+     */
+    public static String padl(final String s, final int size, final char c) {
+        final StringBuilder sb = new StringBuilder(size);
+        if (s != null) {
+            final int len = s.length();
+            if (s.length() <= size) {
+                sb.append(String.valueOf(c).repeat(size - len));
+                sb.append(s);
+            } else {
+                return s.substring(len - size, len);
+            }
+        } else {
+            sb.append(String.valueOf(c).repeat(Math.max(0, size)));
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓�(鍒嗛殧绗﹂粯璁ら�楀彿)
+     *
+     * @param str 琚垏鍒嗙殑瀛楃涓�
+     * @return 鍒嗗壊鍚庣殑鏁版嵁鍒楄〃
+     */
+    public static List<String> splitList(String str) {
+        return splitTo(str, Convert::toStr);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓�
+     *
+     * @param str       琚垏鍒嗙殑瀛楃涓�
+     * @param separator 鍒嗛殧绗�
+     * @return 鍒嗗壊鍚庣殑鏁版嵁鍒楄〃
+     */
+    public static List<String> splitList(String str, String separator) {
+        return splitTo(str, separator, Convert::toStr);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓茶嚜瀹氫箟杞崲(鍒嗛殧绗﹂粯璁ら�楀彿)
+     *
+     * @param str    琚垏鍒嗙殑瀛楃涓�
+     * @param mapper 鑷畾涔夎浆鎹�
+     * @return 鍒嗗壊鍚庣殑鏁版嵁鍒楄〃
+     */
+    public static <T> List<T> splitTo(String str, Function<? super Object, T> mapper) {
+        return splitTo(str, SEPARATOR, mapper);
+    }
+
+    /**
+     * 鍒囧垎瀛楃涓茶嚜瀹氫箟杞崲
+     *
+     * @param str       琚垏鍒嗙殑瀛楃涓�
+     * @param separator 鍒嗛殧绗�
+     * @param mapper    鑷畾涔夎浆鎹�
+     * @return 鍒嗗壊鍚庣殑鏁版嵁鍒楄〃
+     */
+    public static <T> List<T> splitTo(String str, String separator, Function<? super Object, T> mapper) {
+        if (isBlank(str)) {
+            return new ArrayList<>(0);
+        }
+        return StrUtil.split(str, separator)
+            .stream()
+            .filter(Objects::nonNull)
+            .map(mapper)
+            .collect(Collectors.toList());
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Threads.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Threads.java
new file mode 100644
index 0000000..ae6cfa3
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Threads.java
@@ -0,0 +1,75 @@
+package org.dromara.common.core.utils;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.concurrent.*;
+
+/**
+ * 绾跨▼鐩稿叧宸ュ叿绫�.
+ *
+ * @author ruoyi
+ */
+@Slf4j
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class Threads {
+
+    /**
+     * sleep绛夊緟,鍗曚綅涓烘绉�
+     */
+    public static void sleep(long milliseconds) {
+        try {
+            Thread.sleep(milliseconds);
+        } catch (InterruptedException e) {
+            return;
+        }
+    }
+
+    /**
+     * 鍋滄绾跨▼姹�
+     * 鍏堜娇鐢╯hutdown, 鍋滄鎺ユ敹鏂颁换鍔″苟灏濊瘯瀹屾垚鎵�鏈夊凡瀛樺湪浠诲姟.
+     * 濡傛灉瓒呮椂, 鍒欒皟鐢╯hutdownNow, 鍙栨秷鍦╳orkQueue涓璓ending鐨勪换鍔�,骞朵腑鏂墍鏈夐樆濉炲嚱鏁�.
+     * 濡傛灉浠嶇劧瓒呮檪锛屽墖寮峰埗閫�鍑�.
+     * 鍙﹀鍦╯hutdown鏃剁嚎绋嬫湰韬璋冪敤涓柇鍋氫簡澶勭悊.
+     */
+    public static void shutdownAndAwaitTermination(ExecutorService pool) {
+        if (pool != null && !pool.isShutdown()) {
+            pool.shutdown();
+            try {
+                if (!pool.awaitTermination(120, TimeUnit.SECONDS)) {
+                    pool.shutdownNow();
+                    if (!pool.awaitTermination(120, TimeUnit.SECONDS)) {
+                        log.info("Pool did not terminate");
+                    }
+                }
+            } catch (InterruptedException ie) {
+                pool.shutdownNow();
+                Thread.currentThread().interrupt();
+            }
+        }
+    }
+
+    /**
+     * 鎵撳嵃绾跨▼寮傚父淇℃伅
+     */
+    public static void printException(Runnable r, Throwable t) {
+        if (t == null && r instanceof Future<?>) {
+            try {
+                Future<?> future = (Future<?>) r;
+                if (future.isDone()) {
+                    future.get();
+                }
+            } catch (CancellationException ce) {
+                t = ce;
+            } catch (ExecutionException ee) {
+                t = ee.getCause();
+            } catch (InterruptedException ie) {
+                Thread.currentThread().interrupt();
+            }
+        }
+        if (t != null) {
+            log.error(t.getMessage(), t);
+        }
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/TreeBuildUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/TreeBuildUtils.java
new file mode 100644
index 0000000..d0163e6
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/TreeBuildUtils.java
@@ -0,0 +1,35 @@
+package org.dromara.common.core.utils;
+
+import cn.hutool.core.collection.CollUtil;
+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 org.dromara.common.core.utils.reflect.ReflectUtils;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * 鎵╁睍 hutool TreeUtil 灏佽绯荤粺鏍戞瀯寤�
+ *
+ * @author Lion Li
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class TreeBuildUtils extends TreeUtil {
+
+    /**
+     * 鏍规嵁鍓嶇瀹氬埗宸紓鍖栧瓧娈�
+     */
+    public static final TreeNodeConfig DEFAULT_CONFIG = TreeNodeConfig.DEFAULT_CONFIG.setNameKey("label");
+
+    public static <T, K> List<Tree<K>> build(List<T> list, NodeParser<T, K> nodeParser) {
+        if (CollUtil.isEmpty(list)) {
+            return null;
+        }
+        K k = ReflectUtils.invokeGetter(list.get(0), "parentId");
+        return TreeUtil.build(list, k, DEFAULT_CONFIG, nodeParser);
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ValidatorUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ValidatorUtils.java
new file mode 100644
index 0000000..f94f916
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ValidatorUtils.java
@@ -0,0 +1,28 @@
+package org.dromara.common.core.utils;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import jakarta.validation.ConstraintViolation;
+import jakarta.validation.ConstraintViolationException;
+import jakarta.validation.Validator;
+import java.util.Set;
+
+/**
+ * Validator 鏍¢獙妗嗘灦宸ュ叿
+ *
+ * @author Lion Li
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class ValidatorUtils {
+
+    private static final Validator VALID = SpringUtils.getBean(Validator.class);
+
+    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/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/file/FileUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/file/FileUtils.java
new file mode 100644
index 0000000..573b207
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/file/FileUtils.java
@@ -0,0 +1,43 @@
+package org.dromara.common.core.utils.file;
+
+import cn.hutool.core.io.FileUtil;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * 鏂囦欢澶勭悊宸ュ叿绫�
+ *
+ * @author Lion Li
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class FileUtils extends FileUtil {
+
+    /**
+     * 涓嬭浇鏂囦欢鍚嶉噸鏂扮紪鐮�
+     *
+     * @param response     鍝嶅簲瀵硅薄
+     * @param realFileName 鐪熷疄鏂囦欢鍚�
+     */
+    public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) {
+        String percentEncodedFileName = percentEncode(realFileName);
+        String contentDispositionValue = "attachment; filename=%s;filename*=utf-8''%s".formatted(percentEncodedFileName, percentEncodedFileName);
+        response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename");
+        response.setHeader("Content-disposition", contentDispositionValue);
+        response.setHeader("download-filename", percentEncodedFileName);
+    }
+
+    /**
+     * 鐧惧垎鍙风紪鐮佸伐鍏锋柟娉�
+     *
+     * @param s 闇�瑕佺櫨鍒嗗彿缂栫爜鐨勫瓧绗︿覆
+     * @return 鐧惧垎鍙风紪鐮佸悗鐨勫瓧绗︿覆
+     */
+    public static String percentEncode(String s) {
+        String encode = URLEncoder.encode(s, StandardCharsets.UTF_8);
+        return encode.replaceAll("\\+", "%20");
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/file/MimeTypeUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/file/MimeTypeUtils.java
new file mode 100644
index 0000000..23fa2cf
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/file/MimeTypeUtils.java
@@ -0,0 +1,40 @@
+package org.dromara.common.core.utils.file;
+
+/**
+ * 濯掍綋绫诲瀷宸ュ叿绫�
+ *
+ * @author ruoyi
+ */
+public class MimeTypeUtils {
+    public static final String IMAGE_PNG = "image/png";
+
+    public static final String IMAGE_JPG = "image/jpg";
+
+    public static final String IMAGE_JPEG = "image/jpeg";
+
+    public static final String IMAGE_BMP = "image/bmp";
+
+    public static final String IMAGE_GIF = "image/gif";
+
+    public static final String[] IMAGE_EXTENSION = {"bmp", "gif", "jpg", "jpeg", "png"};
+
+    public static final String[] FLASH_EXTENSION = {"swf", "flv"};
+
+    public static final String[] MEDIA_EXTENSION = {"swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg",
+        "asf", "rm", "rmvb"};
+
+    public static final String[] VIDEO_EXTENSION = {"mp4", "avi", "rmvb"};
+
+    public static final String[] DEFAULT_ALLOWED_EXTENSION = {
+        // 鍥剧墖
+        "bmp", "gif", "jpg", "jpeg", "png",
+        // word excel powerpoint
+        "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
+        // 鍘嬬缉鏂囦欢
+        "rar", "zip", "gz", "bz2",
+        // 瑙嗛鏍煎紡
+        "mp4", "avi", "rmvb",
+        // pdf
+        "pdf"};
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/AddressUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/AddressUtils.java
new file mode 100644
index 0000000..a379878
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/AddressUtils.java
@@ -0,0 +1,33 @@
+package org.dromara.common.core.utils.ip;
+
+import cn.hutool.core.net.NetUtil;
+import cn.hutool.http.HtmlUtil;
+import org.dromara.common.core.utils.StringUtils;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 鑾峰彇鍦板潃绫�
+ *
+ * @author Lion Li
+ */
+@Slf4j
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class AddressUtils {
+
+    // 鏈煡鍦板潃
+    public static final String UNKNOWN = "XX XX";
+
+    public static String getRealAddressByIP(String ip) {
+        if (StringUtils.isBlank(ip)) {
+            return UNKNOWN;
+        }
+        // 鍐呯綉涓嶆煡璇�
+        ip = "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : HtmlUtil.cleanHtmlTag(ip);
+        if (NetUtil.isInnerIP(ip)) {
+            return "鍐呯綉IP";
+        }
+        return RegionUtils.getCityInfo(ip);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/RegionUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/RegionUtils.java
new file mode 100644
index 0000000..6e2a44e
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/RegionUtils.java
@@ -0,0 +1,67 @@
+package org.dromara.common.core.utils.ip;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.resource.ClassPathResource;
+import cn.hutool.core.util.ObjectUtil;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.file.FileUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.lionsoul.ip2region.xdb.Searcher;
+
+import java.io.File;
+
+/**
+ * 鏍规嵁ip鍦板潃瀹氫綅宸ュ叿绫伙紝绂荤嚎鏂瑰紡
+ * 鍙傝�冨湴鍧�锛�<a href="https://gitee.com/lionsoul/ip2region/tree/master/binding/java">闆嗘垚 ip2region 瀹炵幇绂荤嚎IP鍦板潃瀹氫綅搴�</a>
+ *
+ * @author lishuyan
+ */
+@Slf4j
+public class RegionUtils {
+
+    private static final Searcher SEARCHER;
+
+    static {
+        String fileName = "/ip2region.xdb";
+        File existFile = FileUtils.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + fileName);
+        if (!FileUtils.exist(existFile)) {
+            ClassPathResource fileStream = new ClassPathResource(fileName);
+            if (ObjectUtil.isEmpty(fileStream.getStream())) {
+                throw new ServiceException("RegionUtils鍒濆鍖栧け璐ワ紝鍘熷洜锛欼P鍦板潃搴撴暟鎹笉瀛樺湪锛�");
+            }
+            FileUtils.writeFromStream(fileStream.getStream(), existFile);
+        }
+
+        String dbPath = existFile.getPath();
+
+        // 1銆佷粠 dbPath 鍔犺浇鏁翠釜 xdb 鍒板唴瀛樸��
+        byte[] cBuff;
+        try {
+            cBuff = Searcher.loadContentFromFile(dbPath);
+        } catch (Exception e) {
+            throw new ServiceException("RegionUtils鍒濆鍖栧け璐ワ紝鍘熷洜锛氫粠ip2region.xdb鏂囦欢鍔犺浇鍐呭澶辫触锛�" + e.getMessage());
+        }
+        // 2銆佷娇鐢ㄤ笂杩扮殑 cBuff 鍒涘缓涓�涓畬鍏ㄥ熀浜庡唴瀛樼殑鏌ヨ瀵硅薄銆�
+        try {
+            SEARCHER = Searcher.newWithBuffer(cBuff);
+        } catch (Exception e) {
+            throw new ServiceException("RegionUtils鍒濆鍖栧け璐ワ紝鍘熷洜锛�" + e.getMessage());
+        }
+    }
+
+    /**
+     * 鏍规嵁IP鍦板潃绂荤嚎鑾峰彇鍩庡競
+     */
+    public static String getCityInfo(String ip) {
+        try {
+            ip = ip.trim();
+            // 3銆佹墽琛屾煡璇�
+            String region = SEARCHER.search(ip);
+            return region.replace("0|", "").replace("|0", "");
+        } catch (Exception e) {
+            log.error("IP鍦板潃绂荤嚎鑾峰彇鍩庡競寮傚父 {}", ip);
+            return "鏈煡";
+        }
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/reflect/ReflectUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/reflect/ReflectUtils.java
new file mode 100644
index 0000000..367e8c9
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/reflect/ReflectUtils.java
@@ -0,0 +1,56 @@
+package org.dromara.common.core.utils.reflect;
+
+import cn.hutool.core.util.ReflectUtil;
+import org.dromara.common.core.utils.StringUtils;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import java.lang.reflect.Method;
+
+/**
+ * 鍙嶅皠宸ュ叿绫�. 鎻愪緵璋冪敤getter/setter鏂规硶, 璁块棶绉佹湁鍙橀噺, 璋冪敤绉佹湁鏂规硶, 鑾峰彇娉涘瀷绫诲瀷Class, 琚獳OP杩囩殑鐪熷疄绫荤瓑宸ュ叿鍑芥暟.
+ *
+ * @author Lion Li
+ */
+@SuppressWarnings("rawtypes")
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class ReflectUtils extends ReflectUtil {
+
+    private static final String SETTER_PREFIX = "set";
+
+    private static final String GETTER_PREFIX = "get";
+
+    /**
+     * 璋冪敤Getter鏂规硶.
+     * 鏀寔澶氱骇锛屽锛氬璞″悕.瀵硅薄鍚�.鏂规硶
+     */
+    @SuppressWarnings("unchecked")
+    public static <E> E invokeGetter(Object obj, String propertyName) {
+        Object object = obj;
+        for (String name : StringUtils.split(propertyName, ".")) {
+            String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name);
+            object = invoke(object, getterMethodName);
+        }
+        return (E) object;
+    }
+
+    /**
+     * 璋冪敤Setter鏂规硶, 浠呭尮閰嶆柟娉曞悕銆�
+     * 鏀寔澶氱骇锛屽锛氬璞″悕.瀵硅薄鍚�.鏂规硶
+     */
+    public static <E> void invokeSetter(Object obj, String propertyName, E value) {
+        Object object = obj;
+        String[] names = StringUtils.split(propertyName, ".");
+        for (int i = 0; i < names.length; i++) {
+            if (i < names.length - 1) {
+                String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]);
+                object = invoke(object, getterMethodName);
+            } else {
+                String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]);
+                Method method = getMethodByName(object.getClass(), setterMethodName);
+                invoke(object, method, value);
+            }
+        }
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sql/SqlUtil.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sql/SqlUtil.java
new file mode 100644
index 0000000..1ed01a9
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sql/SqlUtil.java
@@ -0,0 +1,57 @@
+package org.dromara.common.core.utils.sql;
+
+import org.dromara.common.core.exception.UtilException;
+import org.dromara.common.core.utils.StringUtils;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+/**
+ * sql鎿嶄綔宸ュ叿绫�
+ *
+ * @author ruoyi
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class SqlUtil {
+
+    /**
+     * 瀹氫箟甯哥敤鐨� sql鍏抽敭瀛�
+     */
+    public static final String SQL_REGEX = "select |insert |delete |update |drop |count |exec |chr |mid |master |truncate |char |and |declare ";
+
+    /**
+     * 浠呮敮鎸佸瓧姣嶃�佹暟瀛椼�佷笅鍒掔嚎銆佺┖鏍笺�侀�楀彿銆佸皬鏁扮偣锛堟敮鎸佸涓瓧娈垫帓搴忥級
+     */
+    public static final String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+";
+
+    /**
+     * 妫�鏌ュ瓧绗︼紝闃叉娉ㄥ叆缁曡繃
+     */
+    public static String escapeOrderBySql(String value) {
+        if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) {
+            throw new UtilException("鍙傛暟涓嶇鍚堣鑼冿紝涓嶈兘杩涜鏌ヨ");
+        }
+        return value;
+    }
+
+    /**
+     * 楠岃瘉 order by 璇硶鏄惁绗﹀悎瑙勮寖
+     */
+    public static boolean isValidOrderBySql(String value) {
+        return value.matches(SQL_PATTERN);
+    }
+
+    /**
+     * SQL鍏抽敭瀛楁鏌�
+     */
+    public static void filterKeyword(String value) {
+        if (StringUtils.isEmpty(value)) {
+            return;
+        }
+        String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");
+        for (String sqlKeyword : sqlKeywords) {
+            if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1) {
+                throw new UtilException("鍙傛暟瀛樺湪SQL娉ㄥ叆椋庨櫓");
+            }
+        }
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/AddGroup.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/AddGroup.java
new file mode 100644
index 0000000..0275899
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/AddGroup.java
@@ -0,0 +1,9 @@
+package org.dromara.common.core.validate;
+
+/**
+ * 鏍¢獙鍒嗙粍 add
+ *
+ * @author Lion Li
+ */
+public interface AddGroup {
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/EditGroup.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/EditGroup.java
new file mode 100644
index 0000000..77c5040
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/EditGroup.java
@@ -0,0 +1,9 @@
+package org.dromara.common.core.validate;
+
+/**
+ * 鏍¢獙鍒嗙粍 edit
+ *
+ * @author Lion Li
+ */
+public interface EditGroup {
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/QueryGroup.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/QueryGroup.java
new file mode 100644
index 0000000..02a0ac2
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/QueryGroup.java
@@ -0,0 +1,9 @@
+package org.dromara.common.core.validate;
+
+/**
+ * 鏍¢獙鍒嗙粍 query
+ *
+ * @author Lion Li
+ */
+public interface QueryGroup {
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/xss/Xss.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/xss/Xss.java
new file mode 100644
index 0000000..eed495f
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/xss/Xss.java
@@ -0,0 +1,26 @@
+package org.dromara.common.core.xss;
+
+import jakarta.validation.Constraint;
+import jakarta.validation.Payload;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 鑷畾涔墄ss鏍¢獙娉ㄨВ
+ *
+ * @author Lion Li
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = {ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
+@Constraint(validatedBy = {XssValidator.class})
+public @interface Xss {
+
+    String message() default "涓嶅厑璁镐换浣曡剼鏈繍琛�";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/xss/XssValidator.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/xss/XssValidator.java
new file mode 100644
index 0000000..9c32563
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/xss/XssValidator.java
@@ -0,0 +1,21 @@
+package org.dromara.common.core.xss;
+
+import cn.hutool.core.util.ReUtil;
+import cn.hutool.http.HtmlUtil;
+
+import jakarta.validation.ConstraintValidator;
+import jakarta.validation.ConstraintValidatorContext;
+
+/**
+ * 鑷畾涔墄ss鏍¢獙娉ㄨВ瀹炵幇
+ *
+ * @author Lion Li
+ */
+public class XssValidator implements ConstraintValidator<Xss, String> {
+
+    @Override
+    public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
+        return !ReUtil.contains(HtmlUtil.RE_HTML_MARK, value);
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index 3b13226..3395e73 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-common/ruoyi-common-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1,6 +1,6 @@
-com.ruoyi.common.core.config.ApplicationConfig
-com.ruoyi.common.core.config.AsyncConfig
-com.ruoyi.common.core.config.RuoYiConfig
-com.ruoyi.common.core.config.ThreadPoolConfig
-com.ruoyi.common.core.config.ValidatorConfig
-com.ruoyi.common.core.utils.SpringUtils
+org.dromara.common.core.config.ApplicationConfig
+org.dromara.common.core.config.AsyncConfig
+org.dromara.common.core.config.RuoYiConfig
+org.dromara.common.core.config.ThreadPoolConfig
+org.dromara.common.core.config.ValidatorConfig
+org.dromara.common.core.utils.SpringUtils
diff --git a/ruoyi-common/ruoyi-common-doc/pom.xml b/ruoyi-common/ruoyi-common-doc/pom.xml
index e2171f4..c519975 100644
--- a/ruoyi-common/ruoyi-common-doc/pom.xml
+++ b/ruoyi-common/ruoyi-common-doc/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-common</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -18,7 +18,7 @@
 
     <dependencies>
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-core</artifactId>
         </dependency>
 
diff --git a/ruoyi-common/ruoyi-common-doc/src/main/java/com/ruoyi/common/doc/config/SwaggerConfig.java b/ruoyi-common/ruoyi-common-doc/src/main/java/com/ruoyi/common/doc/config/SwaggerConfig.java
deleted file mode 100644
index 564cb28..0000000
--- a/ruoyi-common/ruoyi-common-doc/src/main/java/com/ruoyi/common/doc/config/SwaggerConfig.java
+++ /dev/null
@@ -1,126 +0,0 @@
-package com.ruoyi.common.doc.config;
-
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.doc.config.properties.SwaggerProperties;
-import com.ruoyi.common.doc.handler.OpenApiHandler;
-import io.swagger.v3.oas.models.OpenAPI;
-import io.swagger.v3.oas.models.Paths;
-import io.swagger.v3.oas.models.info.Info;
-import io.swagger.v3.oas.models.security.SecurityRequirement;
-import lombok.RequiredArgsConstructor;
-import org.springdoc.core.configuration.SpringDocConfiguration;
-import org.springdoc.core.customizers.OpenApiBuilderCustomizer;
-import org.springdoc.core.customizers.OpenApiCustomizer;
-import org.springdoc.core.customizers.ServerBaseUrlCustomizer;
-import org.springdoc.core.properties.SpringDocConfigProperties;
-import org.springdoc.core.providers.JavadocProvider;
-import org.springdoc.core.service.OpenAPIService;
-import org.springdoc.core.service.SecurityService;
-import org.springdoc.core.utils.PropertyResolverUtils;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.autoconfigure.web.ServerProperties;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-
-/**
- * Swagger 鏂囨。閰嶇疆
- *
- * @author Lion Li
- */
-@RequiredArgsConstructor
-@AutoConfiguration(before = SpringDocConfiguration.class)
-@EnableConfigurationProperties(SwaggerProperties.class)
-@ConditionalOnProperty(name = "springdoc.api-docs.enabled", havingValue = "true", matchIfMissing = true)
-public class SwaggerConfig {
-
-    private final ServerProperties serverProperties;
-
-    @Bean
-    @ConditionalOnMissingBean(OpenAPI.class)
-    public OpenAPI openApi(SwaggerProperties swaggerProperties) {
-        OpenAPI openApi = new OpenAPI();
-        // 鏂囨。鍩烘湰淇℃伅
-        SwaggerProperties.InfoProperties infoProperties = swaggerProperties.getInfo();
-        Info info = convertInfo(infoProperties);
-        openApi.info(info);
-        // 鎵╁睍鏂囨。淇℃伅
-        openApi.externalDocs(swaggerProperties.getExternalDocs());
-        openApi.tags(swaggerProperties.getTags());
-        openApi.paths(swaggerProperties.getPaths());
-        openApi.components(swaggerProperties.getComponents());
-        Set<String> keySet = swaggerProperties.getComponents().getSecuritySchemes().keySet();
-        List<SecurityRequirement> list = new ArrayList<>();
-        SecurityRequirement securityRequirement = new SecurityRequirement();
-        keySet.forEach(securityRequirement::addList);
-        list.add(securityRequirement);
-        openApi.security(list);
-
-        return openApi;
-    }
-
-    private Info convertInfo(SwaggerProperties.InfoProperties infoProperties) {
-        Info info = new Info();
-        info.setTitle(infoProperties.getTitle());
-        info.setDescription(infoProperties.getDescription());
-        info.setContact(infoProperties.getContact());
-        info.setLicense(infoProperties.getLicense());
-        info.setVersion(infoProperties.getVersion());
-        return info;
-    }
-
-    /**
-     * 鑷畾涔� openapi 澶勭悊鍣�
-     */
-    @Bean
-    public OpenAPIService openApiBuilder(Optional<OpenAPI> openAPI,
-                                         SecurityService securityParser,
-                                         SpringDocConfigProperties springDocConfigProperties, PropertyResolverUtils propertyResolverUtils,
-                                         Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomisers,
-                                         Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomisers, Optional<JavadocProvider> javadocProvider) {
-        return new OpenApiHandler(openAPI, securityParser, springDocConfigProperties, propertyResolverUtils, openApiBuilderCustomisers, serverBaseUrlCustomisers, javadocProvider);
-    }
-
-    /**
-     * 瀵瑰凡缁忕敓鎴愬ソ鐨� OpenApi 杩涜鑷畾涔夋搷浣�
-     */
-    @Bean
-    public OpenApiCustomizer openApiCustomiser() {
-        String contextPath = serverProperties.getServlet().getContextPath();
-        String finalContextPath;
-        if (StringUtils.isBlank(contextPath) || "/".equals(contextPath)) {
-            finalContextPath = "";
-        } else {
-            finalContextPath = contextPath;
-        }
-        // 瀵规墍鏈夎矾寰勫鍔犲墠缃笂涓嬫枃璺緞
-        return openApi -> {
-            Paths oldPaths = openApi.getPaths();
-            if (oldPaths instanceof PlusPaths) {
-                return;
-            }
-            PlusPaths newPaths = new PlusPaths();
-            oldPaths.forEach((k, v) -> newPaths.addPathItem(finalContextPath + k, v));
-            openApi.setPaths(newPaths);
-        };
-    }
-
-    /**
-     * 鍗曠嫭浣跨敤涓�涓被渚夸簬鍒ゆ柇 瑙e喅springdoc璺緞鎷兼帴閲嶅闂
-     *
-     * @author Lion Li
-     */
-    static class PlusPaths extends Paths {
-
-        public PlusPaths() {
-            super();
-        }
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-doc/src/main/java/com/ruoyi/common/doc/config/properties/SwaggerProperties.java b/ruoyi-common/ruoyi-common-doc/src/main/java/com/ruoyi/common/doc/config/properties/SwaggerProperties.java
deleted file mode 100644
index 071ea95..0000000
--- a/ruoyi-common/ruoyi-common-doc/src/main/java/com/ruoyi/common/doc/config/properties/SwaggerProperties.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package com.ruoyi.common.doc.config.properties;
-
-import io.swagger.v3.oas.models.Components;
-import io.swagger.v3.oas.models.ExternalDocumentation;
-import io.swagger.v3.oas.models.Paths;
-import io.swagger.v3.oas.models.info.Contact;
-import io.swagger.v3.oas.models.info.License;
-import io.swagger.v3.oas.models.tags.Tag;
-import lombok.Data;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.boot.context.properties.NestedConfigurationProperty;
-
-import java.util.List;
-
-/**
- * swagger 閰嶇疆灞炴��
- *
- * @author Lion Li
- */
-@Data
-@ConfigurationProperties(prefix = "swagger")
-public class SwaggerProperties {
-
-    /**
-     * 鏂囨。鍩烘湰淇℃伅
-     */
-    @NestedConfigurationProperty
-    private InfoProperties info = new InfoProperties();
-
-    /**
-     * 鎵╁睍鏂囨。鍦板潃
-     */
-    @NestedConfigurationProperty
-    private ExternalDocumentation externalDocs;
-
-    /**
-     * 鏍囩
-     */
-    private List<Tag> tags = null;
-
-    /**
-     * 璺緞
-     */
-    @NestedConfigurationProperty
-    private Paths paths = null;
-
-    /**
-     * 缁勪欢
-     */
-    @NestedConfigurationProperty
-    private Components components = null;
-
-    /**
-     * <p>
-     * 鏂囨。鐨勫熀纭�灞炴�т俊鎭�
-     * </p>
-     *
-     * @see io.swagger.v3.oas.models.info.Info
-     *
-     * 涓轰簡 springboot 鑷姩鐢熶骇閰嶇疆鎻愮ず淇℃伅锛屾墍浠ヨ繖閲屽鍒朵竴涓被鍑烘潵
-     */
-    @Data
-    public static class InfoProperties {
-
-        /**
-         * 鏍囬
-         */
-        private String title = null;
-
-        /**
-         * 鎻忚堪
-         */
-        private String description = null;
-
-        /**
-         * 鑱旂郴浜轰俊鎭�
-         */
-        @NestedConfigurationProperty
-        private Contact contact = null;
-
-        /**
-         * 璁稿彲璇�
-         */
-        @NestedConfigurationProperty
-        private License license = null;
-
-        /**
-         * 鐗堟湰
-         */
-        private String version = null;
-
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-doc/src/main/java/com/ruoyi/common/doc/handler/OpenApiHandler.java b/ruoyi-common/ruoyi-common-doc/src/main/java/com/ruoyi/common/doc/handler/OpenApiHandler.java
deleted file mode 100644
index 7894bf1..0000000
--- a/ruoyi-common/ruoyi-common-doc/src/main/java/com/ruoyi/common/doc/handler/OpenApiHandler.java
+++ /dev/null
@@ -1,252 +0,0 @@
-package com.ruoyi.common.doc.handler;
-
-import cn.hutool.core.io.IoUtil;
-import io.swagger.v3.core.jackson.TypeNameResolver;
-import io.swagger.v3.core.util.AnnotationsUtils;
-import io.swagger.v3.oas.annotations.tags.Tags;
-import io.swagger.v3.oas.models.Components;
-import io.swagger.v3.oas.models.OpenAPI;
-import io.swagger.v3.oas.models.Operation;
-import io.swagger.v3.oas.models.Paths;
-import io.swagger.v3.oas.models.tags.Tag;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
-import org.springdoc.core.customizers.OpenApiBuilderCustomizer;
-import org.springdoc.core.customizers.ServerBaseUrlCustomizer;
-import org.springdoc.core.properties.SpringDocConfigProperties;
-import org.springdoc.core.providers.JavadocProvider;
-import org.springdoc.core.service.OpenAPIService;
-import org.springdoc.core.service.SecurityService;
-import org.springdoc.core.utils.PropertyResolverUtils;
-import org.springframework.context.ApplicationContext;
-import org.springframework.core.annotation.AnnotatedElementUtils;
-import org.springframework.util.CollectionUtils;
-import org.springframework.web.method.HandlerMethod;
-
-import java.io.StringReader;
-import java.lang.reflect.Method;
-import java.util.*;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-/**
- * 鑷畾涔� openapi 澶勭悊鍣�
- * 瀵规簮鐮佸姛鑳借繘琛屼慨鏀� 澧炲己浣跨敤
- */
-@Slf4j
-@SuppressWarnings("all")
-public class OpenApiHandler extends OpenAPIService {
-
-    /**
-     * The Basic error controller.
-     */
-    private static Class<?> basicErrorController;
-
-    /**
-     * The Security parser.
-     */
-    private final SecurityService securityParser;
-
-    /**
-     * The Mappings map.
-     */
-    private final Map<String, Object> mappingsMap = new HashMap<>();
-
-    /**
-     * The Springdoc tags.
-     */
-    private final Map<HandlerMethod, Tag> springdocTags = new HashMap<>();
-
-    /**
-     * The Open api builder customisers.
-     */
-    private final Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomisers;
-
-    /**
-     * The server base URL customisers.
-     */
-    private final Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomizers;
-
-    /**
-     * The Spring doc config properties.
-     */
-    private final SpringDocConfigProperties springDocConfigProperties;
-
-    /**
-     * The Cached open api map.
-     */
-    private final Map<String, OpenAPI> cachedOpenAPI = new HashMap<>();
-
-    /**
-     * The Property resolver utils.
-     */
-    private final PropertyResolverUtils propertyResolverUtils;
-
-    /**
-     * The javadoc provider.
-     */
-    private final Optional<JavadocProvider> javadocProvider;
-
-    /**
-     * The Context.
-     */
-    private ApplicationContext context;
-
-    /**
-     * The Open api.
-     */
-    private OpenAPI openAPI;
-
-    /**
-     * The Is servers present.
-     */
-    private boolean isServersPresent;
-
-    /**
-     * The Server base url.
-     */
-    private String serverBaseUrl;
-
-    /**
-     * Instantiates a new Open api builder.
-     *
-     * @param openAPI                   the open api
-     * @param securityParser            the security parser
-     * @param springDocConfigProperties the spring doc config properties
-     * @param propertyResolverUtils     the property resolver utils
-     * @param openApiBuilderCustomizers the open api builder customisers
-     * @param serverBaseUrlCustomizers  the server base url customizers
-     * @param javadocProvider           the javadoc provider
-     */
-    public OpenApiHandler(Optional<OpenAPI> openAPI, SecurityService securityParser,
-                          SpringDocConfigProperties springDocConfigProperties, PropertyResolverUtils propertyResolverUtils,
-                          Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomizers,
-                          Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomizers,
-                          Optional<JavadocProvider> javadocProvider) {
-        super(openAPI, securityParser, springDocConfigProperties, propertyResolverUtils, openApiBuilderCustomizers, serverBaseUrlCustomizers, javadocProvider);
-        if (openAPI.isPresent()) {
-            this.openAPI = openAPI.get();
-            if (this.openAPI.getComponents() == null)
-                this.openAPI.setComponents(new Components());
-            if (this.openAPI.getPaths() == null)
-                this.openAPI.setPaths(new Paths());
-            if (!CollectionUtils.isEmpty(this.openAPI.getServers()))
-                this.isServersPresent = true;
-        }
-        this.propertyResolverUtils = propertyResolverUtils;
-        this.securityParser = securityParser;
-        this.springDocConfigProperties = springDocConfigProperties;
-        this.openApiBuilderCustomisers = openApiBuilderCustomizers;
-        this.serverBaseUrlCustomizers = serverBaseUrlCustomizers;
-        this.javadocProvider = javadocProvider;
-        if (springDocConfigProperties.isUseFqn())
-            TypeNameResolver.std.setUseFqn(true);
-    }
-
-    @Override
-    public Operation buildTags(HandlerMethod handlerMethod, Operation operation, OpenAPI openAPI, Locale locale) {
-
-        Set<Tag> tags = new HashSet<>();
-        Set<String> tagsStr = new HashSet<>();
-
-        buildTagsFromMethod(handlerMethod.getMethod(), tags, tagsStr, locale);
-        buildTagsFromClass(handlerMethod.getBeanType(), tags, tagsStr, locale);
-
-        if (!CollectionUtils.isEmpty(tagsStr))
-            tagsStr = tagsStr.stream()
-                .map(str -> propertyResolverUtils.resolve(str, locale))
-                .collect(Collectors.toSet());
-
-        if (springdocTags.containsKey(handlerMethod)) {
-            io.swagger.v3.oas.models.tags.Tag tag = springdocTags.get(handlerMethod);
-            tagsStr.add(tag.getName());
-            if (openAPI.getTags() == null || !openAPI.getTags().contains(tag)) {
-                openAPI.addTagsItem(tag);
-            }
-        }
-
-        if (!CollectionUtils.isEmpty(tagsStr)) {
-            if (CollectionUtils.isEmpty(operation.getTags()))
-                operation.setTags(new ArrayList<>(tagsStr));
-            else {
-                Set<String> operationTagsSet = new HashSet<>(operation.getTags());
-                operationTagsSet.addAll(tagsStr);
-                operation.getTags().clear();
-                operation.getTags().addAll(operationTagsSet);
-            }
-        }
-
-        if (isAutoTagClasses(operation)) {
-
-
-            if (javadocProvider.isPresent()) {
-                String description = javadocProvider.get().getClassJavadoc(handlerMethod.getBeanType());
-                if (StringUtils.isNotBlank(description)) {
-                    io.swagger.v3.oas.models.tags.Tag tag = new io.swagger.v3.oas.models.tags.Tag();
-
-                    // 鑷畾涔夐儴鍒� 淇敼浣跨敤java娉ㄩ噴褰搕ag鍚�
-                    List<String> list = IoUtil.readLines(new StringReader(description), new ArrayList<>());
-                    // tag.setName(tagAutoName);
-                    tag.setName(list.get(0));
-                    operation.addTagsItem(list.get(0));
-
-                    tag.setDescription(description);
-                    if (openAPI.getTags() == null || !openAPI.getTags().contains(tag)) {
-                        openAPI.addTagsItem(tag);
-                    }
-                }
-            } else {
-                String tagAutoName = splitCamelCase(handlerMethod.getBeanType().getSimpleName());
-                operation.addTagsItem(tagAutoName);
-            }
-        }
-
-        if (!CollectionUtils.isEmpty(tags)) {
-            // Existing tags
-            List<io.swagger.v3.oas.models.tags.Tag> openApiTags = openAPI.getTags();
-            if (!CollectionUtils.isEmpty(openApiTags))
-                tags.addAll(openApiTags);
-            openAPI.setTags(new ArrayList<>(tags));
-        }
-
-        // Handle SecurityRequirement at operation level
-        io.swagger.v3.oas.annotations.security.SecurityRequirement[] securityRequirements = securityParser
-            .getSecurityRequirements(handlerMethod);
-        if (securityRequirements != null) {
-            if (securityRequirements.length == 0)
-                operation.setSecurity(Collections.emptyList());
-            else
-                securityParser.buildSecurityRequirement(securityRequirements, operation);
-        }
-
-        return operation;
-    }
-
-    private void buildTagsFromMethod(Method method, Set<io.swagger.v3.oas.models.tags.Tag> tags, Set<String> tagsStr, Locale locale) {
-        // method tags
-        Set<Tags> tagsSet = AnnotatedElementUtils
-            .findAllMergedAnnotations(method, Tags.class);
-        Set<io.swagger.v3.oas.annotations.tags.Tag> methodTags = tagsSet.stream()
-            .flatMap(x -> Stream.of(x.value())).collect(Collectors.toSet());
-        methodTags.addAll(AnnotatedElementUtils.findAllMergedAnnotations(method, io.swagger.v3.oas.annotations.tags.Tag.class));
-        if (!CollectionUtils.isEmpty(methodTags)) {
-            tagsStr.addAll(methodTags.stream().map(tag -> propertyResolverUtils.resolve(tag.name(), locale)).collect(Collectors.toSet()));
-            List<io.swagger.v3.oas.annotations.tags.Tag> allTags = new ArrayList<>(methodTags);
-            addTags(allTags, tags, locale);
-        }
-    }
-
-    private void addTags(List<io.swagger.v3.oas.annotations.tags.Tag> sourceTags, Set<io.swagger.v3.oas.models.tags.Tag> tags, Locale locale) {
-        Optional<Set<io.swagger.v3.oas.models.tags.Tag>> optionalTagSet = AnnotationsUtils
-            .getTags(sourceTags.toArray(new io.swagger.v3.oas.annotations.tags.Tag[0]), true);
-        optionalTagSet.ifPresent(tagsSet -> {
-            tagsSet.forEach(tag -> {
-                tag.name(propertyResolverUtils.resolve(tag.getName(), locale));
-                tag.description(propertyResolverUtils.resolve(tag.getDescription(), locale));
-                if (tags.stream().noneMatch(t -> t.getName().equals(tag.getName())))
-                    tags.add(tag);
-            });
-        });
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/config/SwaggerConfig.java b/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/config/SwaggerConfig.java
new file mode 100644
index 0000000..5579663
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/config/SwaggerConfig.java
@@ -0,0 +1,126 @@
+package org.dromara.common.doc.config;
+
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.doc.config.properties.SwaggerProperties;
+import org.dromara.common.doc.handler.OpenApiHandler;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.Paths;
+import io.swagger.v3.oas.models.info.Info;
+import io.swagger.v3.oas.models.security.SecurityRequirement;
+import lombok.RequiredArgsConstructor;
+import org.springdoc.core.configuration.SpringDocConfiguration;
+import org.springdoc.core.customizers.OpenApiBuilderCustomizer;
+import org.springdoc.core.customizers.OpenApiCustomizer;
+import org.springdoc.core.customizers.ServerBaseUrlCustomizer;
+import org.springdoc.core.properties.SpringDocConfigProperties;
+import org.springdoc.core.providers.JavadocProvider;
+import org.springdoc.core.service.OpenAPIService;
+import org.springdoc.core.service.SecurityService;
+import org.springdoc.core.utils.PropertyResolverUtils;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.web.ServerProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * Swagger 鏂囨。閰嶇疆
+ *
+ * @author Lion Li
+ */
+@RequiredArgsConstructor
+@AutoConfiguration(before = SpringDocConfiguration.class)
+@EnableConfigurationProperties(SwaggerProperties.class)
+@ConditionalOnProperty(name = "springdoc.api-docs.enabled", havingValue = "true", matchIfMissing = true)
+public class SwaggerConfig {
+
+    private final ServerProperties serverProperties;
+
+    @Bean
+    @ConditionalOnMissingBean(OpenAPI.class)
+    public OpenAPI openApi(SwaggerProperties swaggerProperties) {
+        OpenAPI openApi = new OpenAPI();
+        // 鏂囨。鍩烘湰淇℃伅
+        SwaggerProperties.InfoProperties infoProperties = swaggerProperties.getInfo();
+        Info info = convertInfo(infoProperties);
+        openApi.info(info);
+        // 鎵╁睍鏂囨。淇℃伅
+        openApi.externalDocs(swaggerProperties.getExternalDocs());
+        openApi.tags(swaggerProperties.getTags());
+        openApi.paths(swaggerProperties.getPaths());
+        openApi.components(swaggerProperties.getComponents());
+        Set<String> keySet = swaggerProperties.getComponents().getSecuritySchemes().keySet();
+        List<SecurityRequirement> list = new ArrayList<>();
+        SecurityRequirement securityRequirement = new SecurityRequirement();
+        keySet.forEach(securityRequirement::addList);
+        list.add(securityRequirement);
+        openApi.security(list);
+
+        return openApi;
+    }
+
+    private Info convertInfo(SwaggerProperties.InfoProperties infoProperties) {
+        Info info = new Info();
+        info.setTitle(infoProperties.getTitle());
+        info.setDescription(infoProperties.getDescription());
+        info.setContact(infoProperties.getContact());
+        info.setLicense(infoProperties.getLicense());
+        info.setVersion(infoProperties.getVersion());
+        return info;
+    }
+
+    /**
+     * 鑷畾涔� openapi 澶勭悊鍣�
+     */
+    @Bean
+    public OpenAPIService openApiBuilder(Optional<OpenAPI> openAPI,
+                                         SecurityService securityParser,
+                                         SpringDocConfigProperties springDocConfigProperties, PropertyResolverUtils propertyResolverUtils,
+                                         Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomisers,
+                                         Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomisers, Optional<JavadocProvider> javadocProvider) {
+        return new OpenApiHandler(openAPI, securityParser, springDocConfigProperties, propertyResolverUtils, openApiBuilderCustomisers, serverBaseUrlCustomisers, javadocProvider);
+    }
+
+    /**
+     * 瀵瑰凡缁忕敓鎴愬ソ鐨� OpenApi 杩涜鑷畾涔夋搷浣�
+     */
+    @Bean
+    public OpenApiCustomizer openApiCustomiser() {
+        String contextPath = serverProperties.getServlet().getContextPath();
+        String finalContextPath;
+        if (StringUtils.isBlank(contextPath) || "/".equals(contextPath)) {
+            finalContextPath = "";
+        } else {
+            finalContextPath = contextPath;
+        }
+        // 瀵规墍鏈夎矾寰勫鍔犲墠缃笂涓嬫枃璺緞
+        return openApi -> {
+            Paths oldPaths = openApi.getPaths();
+            if (oldPaths instanceof PlusPaths) {
+                return;
+            }
+            PlusPaths newPaths = new PlusPaths();
+            oldPaths.forEach((k, v) -> newPaths.addPathItem(finalContextPath + k, v));
+            openApi.setPaths(newPaths);
+        };
+    }
+
+    /**
+     * 鍗曠嫭浣跨敤涓�涓被渚夸簬鍒ゆ柇 瑙e喅springdoc璺緞鎷兼帴閲嶅闂
+     *
+     * @author Lion Li
+     */
+    static class PlusPaths extends Paths {
+
+        public PlusPaths() {
+            super();
+        }
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/config/properties/SwaggerProperties.java b/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/config/properties/SwaggerProperties.java
new file mode 100644
index 0000000..9e08e73
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/config/properties/SwaggerProperties.java
@@ -0,0 +1,94 @@
+package org.dromara.common.doc.config.properties;
+
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.ExternalDocumentation;
+import io.swagger.v3.oas.models.Paths;
+import io.swagger.v3.oas.models.info.Contact;
+import io.swagger.v3.oas.models.info.License;
+import io.swagger.v3.oas.models.tags.Tag;
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.NestedConfigurationProperty;
+
+import java.util.List;
+
+/**
+ * swagger 閰嶇疆灞炴��
+ *
+ * @author Lion Li
+ */
+@Data
+@ConfigurationProperties(prefix = "swagger")
+public class SwaggerProperties {
+
+    /**
+     * 鏂囨。鍩烘湰淇℃伅
+     */
+    @NestedConfigurationProperty
+    private InfoProperties info = new InfoProperties();
+
+    /**
+     * 鎵╁睍鏂囨。鍦板潃
+     */
+    @NestedConfigurationProperty
+    private ExternalDocumentation externalDocs;
+
+    /**
+     * 鏍囩
+     */
+    private List<Tag> tags = null;
+
+    /**
+     * 璺緞
+     */
+    @NestedConfigurationProperty
+    private Paths paths = null;
+
+    /**
+     * 缁勪欢
+     */
+    @NestedConfigurationProperty
+    private Components components = null;
+
+    /**
+     * <p>
+     * 鏂囨。鐨勫熀纭�灞炴�т俊鎭�
+     * </p>
+     *
+     * @see io.swagger.v3.oas.models.info.Info
+     *
+     * 涓轰簡 springboot 鑷姩鐢熶骇閰嶇疆鎻愮ず淇℃伅锛屾墍浠ヨ繖閲屽鍒朵竴涓被鍑烘潵
+     */
+    @Data
+    public static class InfoProperties {
+
+        /**
+         * 鏍囬
+         */
+        private String title = null;
+
+        /**
+         * 鎻忚堪
+         */
+        private String description = null;
+
+        /**
+         * 鑱旂郴浜轰俊鎭�
+         */
+        @NestedConfigurationProperty
+        private Contact contact = null;
+
+        /**
+         * 璁稿彲璇�
+         */
+        @NestedConfigurationProperty
+        private License license = null;
+
+        /**
+         * 鐗堟湰
+         */
+        private String version = null;
+
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/handler/OpenApiHandler.java b/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/handler/OpenApiHandler.java
new file mode 100644
index 0000000..a35cc64
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/handler/OpenApiHandler.java
@@ -0,0 +1,252 @@
+package org.dromara.common.doc.handler;
+
+import cn.hutool.core.io.IoUtil;
+import io.swagger.v3.core.jackson.TypeNameResolver;
+import io.swagger.v3.core.util.AnnotationsUtils;
+import io.swagger.v3.oas.annotations.tags.Tags;
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.Operation;
+import io.swagger.v3.oas.models.Paths;
+import io.swagger.v3.oas.models.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springdoc.core.customizers.OpenApiBuilderCustomizer;
+import org.springdoc.core.customizers.ServerBaseUrlCustomizer;
+import org.springdoc.core.properties.SpringDocConfigProperties;
+import org.springdoc.core.providers.JavadocProvider;
+import org.springdoc.core.service.OpenAPIService;
+import org.springdoc.core.service.SecurityService;
+import org.springdoc.core.utils.PropertyResolverUtils;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.annotation.AnnotatedElementUtils;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.method.HandlerMethod;
+
+import java.io.StringReader;
+import java.lang.reflect.Method;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * 鑷畾涔� openapi 澶勭悊鍣�
+ * 瀵规簮鐮佸姛鑳借繘琛屼慨鏀� 澧炲己浣跨敤
+ */
+@Slf4j
+@SuppressWarnings("all")
+public class OpenApiHandler extends OpenAPIService {
+
+    /**
+     * The Basic error controller.
+     */
+    private static Class<?> basicErrorController;
+
+    /**
+     * The Security parser.
+     */
+    private final SecurityService securityParser;
+
+    /**
+     * The Mappings map.
+     */
+    private final Map<String, Object> mappingsMap = new HashMap<>();
+
+    /**
+     * The Springdoc tags.
+     */
+    private final Map<HandlerMethod, Tag> springdocTags = new HashMap<>();
+
+    /**
+     * The Open api builder customisers.
+     */
+    private final Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomisers;
+
+    /**
+     * The server base URL customisers.
+     */
+    private final Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomizers;
+
+    /**
+     * The Spring doc config properties.
+     */
+    private final SpringDocConfigProperties springDocConfigProperties;
+
+    /**
+     * The Cached open api map.
+     */
+    private final Map<String, OpenAPI> cachedOpenAPI = new HashMap<>();
+
+    /**
+     * The Property resolver utils.
+     */
+    private final PropertyResolverUtils propertyResolverUtils;
+
+    /**
+     * The javadoc provider.
+     */
+    private final Optional<JavadocProvider> javadocProvider;
+
+    /**
+     * The Context.
+     */
+    private ApplicationContext context;
+
+    /**
+     * The Open api.
+     */
+    private OpenAPI openAPI;
+
+    /**
+     * The Is servers present.
+     */
+    private boolean isServersPresent;
+
+    /**
+     * The Server base url.
+     */
+    private String serverBaseUrl;
+
+    /**
+     * Instantiates a new Open api builder.
+     *
+     * @param openAPI                   the open api
+     * @param securityParser            the security parser
+     * @param springDocConfigProperties the spring doc config properties
+     * @param propertyResolverUtils     the property resolver utils
+     * @param openApiBuilderCustomizers the open api builder customisers
+     * @param serverBaseUrlCustomizers  the server base url customizers
+     * @param javadocProvider           the javadoc provider
+     */
+    public OpenApiHandler(Optional<OpenAPI> openAPI, SecurityService securityParser,
+                          SpringDocConfigProperties springDocConfigProperties, PropertyResolverUtils propertyResolverUtils,
+                          Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomizers,
+                          Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomizers,
+                          Optional<JavadocProvider> javadocProvider) {
+        super(openAPI, securityParser, springDocConfigProperties, propertyResolverUtils, openApiBuilderCustomizers, serverBaseUrlCustomizers, javadocProvider);
+        if (openAPI.isPresent()) {
+            this.openAPI = openAPI.get();
+            if (this.openAPI.getComponents() == null)
+                this.openAPI.setComponents(new Components());
+            if (this.openAPI.getPaths() == null)
+                this.openAPI.setPaths(new Paths());
+            if (!CollectionUtils.isEmpty(this.openAPI.getServers()))
+                this.isServersPresent = true;
+        }
+        this.propertyResolverUtils = propertyResolverUtils;
+        this.securityParser = securityParser;
+        this.springDocConfigProperties = springDocConfigProperties;
+        this.openApiBuilderCustomisers = openApiBuilderCustomizers;
+        this.serverBaseUrlCustomizers = serverBaseUrlCustomizers;
+        this.javadocProvider = javadocProvider;
+        if (springDocConfigProperties.isUseFqn())
+            TypeNameResolver.std.setUseFqn(true);
+    }
+
+    @Override
+    public Operation buildTags(HandlerMethod handlerMethod, Operation operation, OpenAPI openAPI, Locale locale) {
+
+        Set<Tag> tags = new HashSet<>();
+        Set<String> tagsStr = new HashSet<>();
+
+        buildTagsFromMethod(handlerMethod.getMethod(), tags, tagsStr, locale);
+        buildTagsFromClass(handlerMethod.getBeanType(), tags, tagsStr, locale);
+
+        if (!CollectionUtils.isEmpty(tagsStr))
+            tagsStr = tagsStr.stream()
+                .map(str -> propertyResolverUtils.resolve(str, locale))
+                .collect(Collectors.toSet());
+
+        if (springdocTags.containsKey(handlerMethod)) {
+            io.swagger.v3.oas.models.tags.Tag tag = springdocTags.get(handlerMethod);
+            tagsStr.add(tag.getName());
+            if (openAPI.getTags() == null || !openAPI.getTags().contains(tag)) {
+                openAPI.addTagsItem(tag);
+            }
+        }
+
+        if (!CollectionUtils.isEmpty(tagsStr)) {
+            if (CollectionUtils.isEmpty(operation.getTags()))
+                operation.setTags(new ArrayList<>(tagsStr));
+            else {
+                Set<String> operationTagsSet = new HashSet<>(operation.getTags());
+                operationTagsSet.addAll(tagsStr);
+                operation.getTags().clear();
+                operation.getTags().addAll(operationTagsSet);
+            }
+        }
+
+        if (isAutoTagClasses(operation)) {
+
+
+            if (javadocProvider.isPresent()) {
+                String description = javadocProvider.get().getClassJavadoc(handlerMethod.getBeanType());
+                if (StringUtils.isNotBlank(description)) {
+                    io.swagger.v3.oas.models.tags.Tag tag = new io.swagger.v3.oas.models.tags.Tag();
+
+                    // 鑷畾涔夐儴鍒� 淇敼浣跨敤java娉ㄩ噴褰搕ag鍚�
+                    List<String> list = IoUtil.readLines(new StringReader(description), new ArrayList<>());
+                    // tag.setName(tagAutoName);
+                    tag.setName(list.get(0));
+                    operation.addTagsItem(list.get(0));
+
+                    tag.setDescription(description);
+                    if (openAPI.getTags() == null || !openAPI.getTags().contains(tag)) {
+                        openAPI.addTagsItem(tag);
+                    }
+                }
+            } else {
+                String tagAutoName = splitCamelCase(handlerMethod.getBeanType().getSimpleName());
+                operation.addTagsItem(tagAutoName);
+            }
+        }
+
+        if (!CollectionUtils.isEmpty(tags)) {
+            // Existing tags
+            List<io.swagger.v3.oas.models.tags.Tag> openApiTags = openAPI.getTags();
+            if (!CollectionUtils.isEmpty(openApiTags))
+                tags.addAll(openApiTags);
+            openAPI.setTags(new ArrayList<>(tags));
+        }
+
+        // Handle SecurityRequirement at operation level
+        io.swagger.v3.oas.annotations.security.SecurityRequirement[] securityRequirements = securityParser
+            .getSecurityRequirements(handlerMethod);
+        if (securityRequirements != null) {
+            if (securityRequirements.length == 0)
+                operation.setSecurity(Collections.emptyList());
+            else
+                securityParser.buildSecurityRequirement(securityRequirements, operation);
+        }
+
+        return operation;
+    }
+
+    private void buildTagsFromMethod(Method method, Set<io.swagger.v3.oas.models.tags.Tag> tags, Set<String> tagsStr, Locale locale) {
+        // method tags
+        Set<Tags> tagsSet = AnnotatedElementUtils
+            .findAllMergedAnnotations(method, Tags.class);
+        Set<io.swagger.v3.oas.annotations.tags.Tag> methodTags = tagsSet.stream()
+            .flatMap(x -> Stream.of(x.value())).collect(Collectors.toSet());
+        methodTags.addAll(AnnotatedElementUtils.findAllMergedAnnotations(method, io.swagger.v3.oas.annotations.tags.Tag.class));
+        if (!CollectionUtils.isEmpty(methodTags)) {
+            tagsStr.addAll(methodTags.stream().map(tag -> propertyResolverUtils.resolve(tag.name(), locale)).collect(Collectors.toSet()));
+            List<io.swagger.v3.oas.annotations.tags.Tag> allTags = new ArrayList<>(methodTags);
+            addTags(allTags, tags, locale);
+        }
+    }
+
+    private void addTags(List<io.swagger.v3.oas.annotations.tags.Tag> sourceTags, Set<io.swagger.v3.oas.models.tags.Tag> tags, Locale locale) {
+        Optional<Set<io.swagger.v3.oas.models.tags.Tag>> optionalTagSet = AnnotationsUtils
+            .getTags(sourceTags.toArray(new io.swagger.v3.oas.annotations.tags.Tag[0]), true);
+        optionalTagSet.ifPresent(tagsSet -> {
+            tagsSet.forEach(tag -> {
+                tag.name(propertyResolverUtils.resolve(tag.getName(), locale));
+                tag.description(propertyResolverUtils.resolve(tag.getDescription(), locale));
+                if (tags.stream().noneMatch(t -> t.getName().equals(tag.getName())))
+                    tags.add(tag);
+            });
+        });
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-doc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-doc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index 8ae5a18..e64b2eb 100644
--- a/ruoyi-common/ruoyi-common-doc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-common/ruoyi-common-doc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +1 @@
-com.ruoyi.common.doc.config.SwaggerConfig
+org.dromara.common.doc.config.SwaggerConfig
diff --git a/ruoyi-common/ruoyi-common-encrypt/pom.xml b/ruoyi-common/ruoyi-common-encrypt/pom.xml
index 22aca40..b873a19 100644
--- a/ruoyi-common/ruoyi-common-encrypt/pom.xml
+++ b/ruoyi-common/ruoyi-common-encrypt/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-common</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -19,7 +19,7 @@
     <dependencies>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-core</artifactId>
         </dependency>
 
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/annotation/EncryptField.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/annotation/EncryptField.java
deleted file mode 100644
index f549a6a..0000000
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/annotation/EncryptField.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package com.ruoyi.common.encrypt.annotation;
-
-import com.ruoyi.common.encrypt.enumd.AlgorithmType;
-import com.ruoyi.common.encrypt.enumd.EncodeType;
-
-import java.lang.annotation.*;
-
-/**
- * 瀛楁鍔犲瘑娉ㄨВ
- *
- * @author 鑰侀┈
- */
-@Documented
-@Inherited
-@Target({ElementType.FIELD})
-@Retention(RetentionPolicy.RUNTIME)
-public @interface EncryptField {
-
-    /**
-     * 鍔犲瘑绠楁硶
-     */
-    AlgorithmType algorithm() default AlgorithmType.DEFAULT;
-
-    /**
-     * 绉橀挜銆侫ES銆丼M4闇�瑕�
-     */
-    String password() default "";
-
-    /**
-     * 鍏挜銆俁SA銆丼M2闇�瑕�
-     */
-    String publicKey() default "";
-
-    /**
-     * 鍏挜銆俁SA銆丼M2闇�瑕�
-     */
-    String privateKey() default "";
-
-    /**
-     * 缂栫爜鏂瑰紡銆傚鍔犲瘑绠楁硶涓築ASE64鐨勪笉璧蜂綔鐢�
-     */
-    EncodeType encode() default EncodeType.DEFAULT;
-
-}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/config/EncryptorAutoConfiguration.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/config/EncryptorAutoConfiguration.java
deleted file mode 100644
index 55be902..0000000
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/config/EncryptorAutoConfiguration.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.ruoyi.common.encrypt.config;
-
-import com.ruoyi.common.encrypt.core.EncryptorManager;
-import com.ruoyi.common.encrypt.interceptor.MybatisDecryptInterceptor;
-import com.ruoyi.common.encrypt.interceptor.MybatisEncryptInterceptor;
-import com.ruoyi.common.encrypt.properties.EncryptorProperties;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-
-/**
- * 鍔犺В瀵嗛厤缃�
- *
- * @author 鑰侀┈
- * @version 4.6.0
- */
-@AutoConfiguration
-@EnableConfigurationProperties(EncryptorProperties.class)
-@ConditionalOnProperty(value = "mybatis-encryptor.enable", havingValue = "true")
-public class EncryptorAutoConfiguration {
-
-    @Autowired
-    private EncryptorProperties properties;
-
-    @Bean
-    public EncryptorManager encryptorManager() {
-        return new EncryptorManager();
-    }
-
-    @Bean
-    public MybatisEncryptInterceptor mybatisEncryptInterceptor(EncryptorManager encryptorManager) {
-        return new MybatisEncryptInterceptor(encryptorManager, properties);
-    }
-
-    @Bean
-    public MybatisDecryptInterceptor mybatisDecryptInterceptor(EncryptorManager encryptorManager) {
-        return new MybatisDecryptInterceptor(encryptorManager, properties);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/EncryptContext.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/EncryptContext.java
deleted file mode 100644
index ff38254..0000000
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/EncryptContext.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.ruoyi.common.encrypt.core;
-
-import com.ruoyi.common.encrypt.enumd.AlgorithmType;
-import com.ruoyi.common.encrypt.enumd.EncodeType;
-import lombok.Data;
-
-/**
- * 鍔犲瘑涓婁笅鏂� 鐢ㄤ簬encryptor浼犻�掑繀瑕佺殑鍙傛暟銆�
- *
- * @author 鑰侀┈
- * @version 4.6.0
- */
-@Data
-public class EncryptContext {
-
-    /**
-     * 榛樿绠楁硶
-     */
-    private AlgorithmType algorithm;
-
-    /**
-     * 瀹夊叏绉橀挜
-     */
-    private String password;
-
-    /**
-     * 鍏挜
-     */
-    private String publicKey;
-
-    /**
-     * 绉侀挜
-     */
-    private String privateKey;
-
-    /**
-     * 缂栫爜鏂瑰紡锛宐ase64/hex
-     */
-    private EncodeType encode;
-
-}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/EncryptorManager.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/EncryptorManager.java
deleted file mode 100644
index d86eb71..0000000
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/EncryptorManager.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package com.ruoyi.common.encrypt.core;
-
-import cn.hutool.core.util.ReflectUtil;
-import com.ruoyi.common.encrypt.annotation.EncryptField;
-import lombok.extern.slf4j.Slf4j;
-
-import java.lang.reflect.Field;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Collectors;
-
-/**
- * 鍔犲瘑绠$悊绫�
- *
- * @author 鑰侀┈
- * @version 4.6.0
- */
-@Slf4j
-public class EncryptorManager {
-
-    /**
-     * 缂撳瓨鍔犲瘑鍣�
-     */
-    Map<EncryptContext, IEncryptor> encryptorMap = new ConcurrentHashMap<>();
-
-    /**
-     * 绫诲姞瀵嗗瓧娈电紦瀛�
-     */
-    Map<Class<?>, Set<Field>> fieldCache = new ConcurrentHashMap<>();
-
-    /**
-     * 鑾峰彇绫诲姞瀵嗗瓧娈电紦瀛�
-     */
-    public Set<Field> getFieldCache(Class<?> sourceClazz) {
-        return fieldCache.computeIfAbsent(sourceClazz, clazz -> {
-            Field[] declaredFields = clazz.getDeclaredFields();
-            Set<Field> fieldSet = Arrays.stream(declaredFields).filter(field ->
-                    field.isAnnotationPresent(EncryptField.class) && field.getType() == String.class)
-                .collect(Collectors.toSet());
-            for (Field field : fieldSet) {
-                field.setAccessible(true);
-            }
-            return fieldSet;
-        });
-    }
-
-    /**
-     * 娉ㄥ唽鍔犲瘑鎵ц鑰呭埌缂撳瓨
-     *
-     * @param encryptContext 鍔犲瘑鎵ц鑰呴渶瑕佺殑鐩稿叧閰嶇疆鍙傛暟
-     */
-    public IEncryptor registAndGetEncryptor(EncryptContext encryptContext) {
-        if (encryptorMap.containsKey(encryptContext)) {
-            return encryptorMap.get(encryptContext);
-        }
-        IEncryptor encryptor = ReflectUtil.newInstance(encryptContext.getAlgorithm().getClazz(), encryptContext);
-        encryptorMap.put(encryptContext, encryptor);
-        return encryptor;
-    }
-
-    /**
-     * 绉婚櫎缂撳瓨涓殑鍔犲瘑鎵ц鑰�
-     *
-     * @param encryptContext 鍔犲瘑鎵ц鑰呴渶瑕佺殑鐩稿叧閰嶇疆鍙傛暟
-     */
-    public void removeEncryptor(EncryptContext encryptContext) {
-        this.encryptorMap.remove(encryptContext);
-    }
-
-    /**
-     * 鏍规嵁閰嶇疆杩涜鍔犲瘑銆備細杩涜鏈湴缂撳瓨瀵瑰簲鐨勭畻娉曞拰瀵瑰簲鐨勭閽ヤ俊鎭��
-     *
-     * @param value          寰呭姞瀵嗙殑鍊�
-     * @param encryptContext 鍔犲瘑鐩稿叧鐨勯厤缃俊鎭�
-     */
-    public String encrypt(String value, EncryptContext encryptContext) {
-        IEncryptor encryptor = this.registAndGetEncryptor(encryptContext);
-        return encryptor.encrypt(value, encryptContext.getEncode());
-    }
-
-    /**
-     * 鏍规嵁閰嶇疆杩涜瑙e瘑
-     *
-     * @param value          寰呰В瀵嗙殑鍊�
-     * @param encryptContext 鍔犲瘑鐩稿叧鐨勯厤缃俊鎭�
-     */
-    public String decrypt(String value, EncryptContext encryptContext) {
-        IEncryptor encryptor = this.registAndGetEncryptor(encryptContext);
-        return encryptor.decrypt(value);
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/IEncryptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/IEncryptor.java
deleted file mode 100644
index d9642c0..0000000
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/IEncryptor.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.ruoyi.common.encrypt.core;
-
-import com.ruoyi.common.encrypt.enumd.AlgorithmType;
-import com.ruoyi.common.encrypt.enumd.EncodeType;
-
-/**
- * 鍔犺В鑰�
- *
- * @author 鑰侀┈
- * @version 4.6.0
- */
-public interface IEncryptor {
-
-    /**
-     * 鑾峰緱褰撳墠绠楁硶
-     */
-    AlgorithmType algorithm();
-
-    /**
-     * 鍔犲瘑
-     *
-     * @param value      寰呭姞瀵嗗瓧绗︿覆
-     * @param encodeType 鍔犲瘑鍚庣殑缂栫爜鏍煎紡
-     * @return 鍔犲瘑鍚庣殑瀛楃涓�
-     */
-    String encrypt(String value, EncodeType encodeType);
-
-    /**
-     * 瑙e瘑
-     *
-     * @param value      寰呭姞瀵嗗瓧绗︿覆
-     * @return 瑙e瘑鍚庣殑瀛楃涓�
-     */
-    String decrypt(String value);
-}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/encryptor/AbstractEncryptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/encryptor/AbstractEncryptor.java
deleted file mode 100644
index b068ce7..0000000
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/encryptor/AbstractEncryptor.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.ruoyi.common.encrypt.core.encryptor;
-
-import com.ruoyi.common.encrypt.core.EncryptContext;
-import com.ruoyi.common.encrypt.core.IEncryptor;
-
-/**
- * 鎵�鏈夊姞瀵嗘墽琛岃�呯殑鍩虹被
- *
- * @author 鑰侀┈
- * @version 4.6.0
- */
-public abstract class AbstractEncryptor implements IEncryptor {
-
-    public AbstractEncryptor(EncryptContext context) {
-        // 鐢ㄦ埛閰嶇疆鏍¢獙涓庨厤缃敞鍏�
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/encryptor/AesEncryptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/encryptor/AesEncryptor.java
deleted file mode 100644
index ea89d2c..0000000
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/encryptor/AesEncryptor.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package com.ruoyi.common.encrypt.core.encryptor;
-
-import cn.hutool.core.util.ArrayUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.crypto.SecureUtil;
-import cn.hutool.crypto.symmetric.AES;
-import com.ruoyi.common.encrypt.core.EncryptContext;
-import com.ruoyi.common.encrypt.enumd.AlgorithmType;
-import com.ruoyi.common.encrypt.enumd.EncodeType;
-
-import java.nio.charset.StandardCharsets;
-
-/**
- * AES绠楁硶瀹炵幇
- *
- * @author 鑰侀┈
- * @version 4.6.0
- */
-public class AesEncryptor extends AbstractEncryptor {
-
-    private final AES aes;
-
-    public AesEncryptor(EncryptContext context) {
-        super(context);
-        String password = context.getPassword();
-        if (StrUtil.isBlank(password)) {
-            throw new IllegalArgumentException("AES娌℃湁鑾峰緱绉橀挜淇℃伅");
-        }
-        // aes绠楁硶鐨勭閽ヨ姹傛槸16浣嶃��24浣嶃��32浣�
-        int[] array = {16, 24, 32};
-        if (!ArrayUtil.contains(array, password.length())) {
-            throw new IllegalArgumentException("AES绉橀挜闀垮害搴旇涓�16浣嶃��24浣嶃��32浣嶏紝瀹為檯涓�" + password.length() + "浣�");
-        }
-        aes = SecureUtil.aes(context.getPassword().getBytes(StandardCharsets.UTF_8));
-    }
-
-    /**
-     * 鑾峰緱褰撳墠绠楁硶
-     */
-    @Override
-    public AlgorithmType algorithm() {
-        return AlgorithmType.AES;
-    }
-
-    /**
-     * 鍔犲瘑
-     *
-     * @param value      寰呭姞瀵嗗瓧绗︿覆
-     * @param encodeType 鍔犲瘑鍚庣殑缂栫爜鏍煎紡
-     */
-    @Override
-    public String encrypt(String value, EncodeType encodeType) {
-        if (encodeType == EncodeType.HEX) {
-            return aes.encryptHex(value);
-        } else {
-            return aes.encryptBase64(value);
-        }
-    }
-
-    /**
-     * 瑙e瘑
-     *
-     * @param value      寰呭姞瀵嗗瓧绗︿覆
-     */
-    @Override
-    public String decrypt(String value) {
-        return this.aes.decryptStr(value);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/encryptor/Base64Encryptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/encryptor/Base64Encryptor.java
deleted file mode 100644
index 70f3e00..0000000
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/encryptor/Base64Encryptor.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.ruoyi.common.encrypt.core.encryptor;
-
-import cn.hutool.core.codec.Base64;
-import com.ruoyi.common.encrypt.core.EncryptContext;
-import com.ruoyi.common.encrypt.enumd.AlgorithmType;
-import com.ruoyi.common.encrypt.enumd.EncodeType;
-
-/**
- * Base64绠楁硶瀹炵幇
- *
- * @author 鑰侀┈
- * @version 4.6.0
- */
-public class Base64Encryptor extends AbstractEncryptor {
-
-    public Base64Encryptor(EncryptContext context) {
-        super(context);
-    }
-
-    /**
-     * 鑾峰緱褰撳墠绠楁硶
-     */
-    @Override
-    public AlgorithmType algorithm() {
-        return AlgorithmType.BASE64;
-    }
-
-    /**
-     * 鍔犲瘑
-     *
-     * @param value      寰呭姞瀵嗗瓧绗︿覆
-     * @param encodeType 鍔犲瘑鍚庣殑缂栫爜鏍煎紡
-     */
-    @Override
-    public String encrypt(String value, EncodeType encodeType) {
-        return Base64.encode(value);
-    }
-
-    /**
-     * 瑙e瘑
-     *
-     * @param value      寰呭姞瀵嗗瓧绗︿覆
-     */
-    @Override
-    public String decrypt(String value) {
-        return Base64.decodeStr(value);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/encryptor/RsaEncryptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/encryptor/RsaEncryptor.java
deleted file mode 100644
index bd7774e..0000000
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/encryptor/RsaEncryptor.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.ruoyi.common.encrypt.core.encryptor;
-
-import cn.hutool.core.codec.Base64;
-import cn.hutool.crypto.SecureUtil;
-import cn.hutool.crypto.asymmetric.KeyType;
-import cn.hutool.crypto.asymmetric.RSA;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.encrypt.core.EncryptContext;
-import com.ruoyi.common.encrypt.enumd.AlgorithmType;
-import com.ruoyi.common.encrypt.enumd.EncodeType;
-
-
-/**
- * RSA绠楁硶瀹炵幇
- *
- * @author 鑰侀┈
- * @version 4.6.0
- */
-public class RsaEncryptor extends AbstractEncryptor {
-
-    private final RSA rsa;
-
-    public RsaEncryptor(EncryptContext context) {
-        super(context);
-        String privateKey = context.getPrivateKey();
-        String publicKey = context.getPublicKey();
-        if (StringUtils.isAnyEmpty(privateKey, publicKey)) {
-            throw new IllegalArgumentException("RSA鍏閽ュ潎闇�瑕佹彁渚涳紝鍏挜鍔犲瘑锛岀閽ヨВ瀵嗐��");
-        }
-        this.rsa = SecureUtil.rsa(Base64.decode(privateKey), Base64.decode(publicKey));
-    }
-
-    /**
-     * 鑾峰緱褰撳墠绠楁硶
-     */
-    @Override
-    public AlgorithmType algorithm() {
-        return AlgorithmType.RSA;
-    }
-
-    /**
-     * 鍔犲瘑
-     *
-     * @param value      寰呭姞瀵嗗瓧绗︿覆
-     * @param encodeType 鍔犲瘑鍚庣殑缂栫爜鏍煎紡
-     */
-    @Override
-    public String encrypt(String value, EncodeType encodeType) {
-        if (encodeType == EncodeType.HEX) {
-            return rsa.encryptHex(value, KeyType.PublicKey);
-        } else {
-            return rsa.encryptBase64(value, KeyType.PublicKey);
-        }
-    }
-
-    /**
-     * 瑙e瘑
-     *
-     * @param value      寰呭姞瀵嗗瓧绗︿覆
-     */
-    @Override
-    public String decrypt(String value) {
-        return this.rsa.decryptStr(value, KeyType.PrivateKey);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/encryptor/Sm2Encryptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/encryptor/Sm2Encryptor.java
deleted file mode 100644
index 1e0bb9f..0000000
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/encryptor/Sm2Encryptor.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package com.ruoyi.common.encrypt.core.encryptor;
-
-import cn.hutool.core.codec.Base64;
-import cn.hutool.crypto.SmUtil;
-import cn.hutool.crypto.asymmetric.KeyType;
-import cn.hutool.crypto.asymmetric.SM2;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.encrypt.core.EncryptContext;
-import com.ruoyi.common.encrypt.enumd.AlgorithmType;
-import com.ruoyi.common.encrypt.enumd.EncodeType;
-
-/**
- * sm2绠楁硶瀹炵幇
- *
- * @author 鑰侀┈
- * @version 4.6.0
- */
-public class Sm2Encryptor extends AbstractEncryptor {
-
-    private final SM2 sm2;
-
-    public Sm2Encryptor(EncryptContext context) {
-        super(context);
-        String privateKey = context.getPrivateKey();
-        String publicKey = context.getPublicKey();
-        if (StringUtils.isAnyEmpty(privateKey, publicKey)) {
-            throw new IllegalArgumentException("SM2鍏閽ュ潎闇�瑕佹彁渚涳紝鍏挜鍔犲瘑锛岀閽ヨВ瀵嗐��");
-        }
-        this.sm2 = SmUtil.sm2(Base64.decode(privateKey), Base64.decode(publicKey));
-    }
-
-    /**
-     * 鑾峰緱褰撳墠绠楁硶
-     */
-    @Override
-    public AlgorithmType algorithm() {
-        return AlgorithmType.SM2;
-    }
-
-    /**
-     * 鍔犲瘑
-     *
-     * @param value      寰呭姞瀵嗗瓧绗︿覆
-     * @param encodeType 鍔犲瘑鍚庣殑缂栫爜鏍煎紡
-     */
-    @Override
-    public String encrypt(String value, EncodeType encodeType) {
-        if (encodeType == EncodeType.HEX) {
-            return sm2.encryptHex(value, KeyType.PublicKey);
-        } else {
-            return sm2.encryptBase64(value, KeyType.PublicKey);
-        }
-    }
-
-    /**
-     * 瑙e瘑
-     *
-     * @param value      寰呭姞瀵嗗瓧绗︿覆
-     */
-    @Override
-    public String decrypt(String value) {
-        return this.sm2.decryptStr(value, KeyType.PrivateKey);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/encryptor/Sm4Encryptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/encryptor/Sm4Encryptor.java
deleted file mode 100644
index b150503..0000000
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/core/encryptor/Sm4Encryptor.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.ruoyi.common.encrypt.core.encryptor;
-
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.crypto.SmUtil;
-import cn.hutool.crypto.symmetric.SM4;
-import com.ruoyi.common.encrypt.core.EncryptContext;
-import com.ruoyi.common.encrypt.enumd.AlgorithmType;
-import com.ruoyi.common.encrypt.enumd.EncodeType;
-
-import java.nio.charset.StandardCharsets;
-
-/**
- * sm4绠楁硶瀹炵幇
- *
- * @author 鑰侀┈
- * @version 4.6.0
- */
-public class Sm4Encryptor extends AbstractEncryptor {
-
-    private final SM4 sm4;
-
-    public Sm4Encryptor(EncryptContext context) {
-        super(context);
-        String password = context.getPassword();
-        if (StrUtil.isBlank(password)) {
-            throw new IllegalArgumentException("SM4娌℃湁鑾峰緱绉橀挜淇℃伅");
-        }
-        // sm4绠楁硶鐨勭閽ヨ姹傛槸16浣嶉暱搴�
-        if (16 != password.length()) {
-            throw new IllegalArgumentException("SM4绉橀挜闀垮害搴旇涓�16浣嶏紝瀹為檯涓�" + password.length() + "浣�");
-        }
-        this.sm4 = SmUtil.sm4(password.getBytes(StandardCharsets.UTF_8));
-    }
-
-    /**
-     * 鑾峰緱褰撳墠绠楁硶
-     */
-    @Override
-    public AlgorithmType algorithm() {
-        return AlgorithmType.SM4;
-    }
-
-    /**
-     * 鍔犲瘑
-     *
-     * @param value      寰呭姞瀵嗗瓧绗︿覆
-     * @param encodeType 鍔犲瘑鍚庣殑缂栫爜鏍煎紡
-     */
-    @Override
-    public String encrypt(String value, EncodeType encodeType) {
-        if (encodeType == EncodeType.HEX) {
-            return sm4.encryptHex(value);
-        } else {
-            return sm4.encryptBase64(value);
-        }
-    }
-
-    /**
-     * 瑙e瘑
-     *
-     * @param value      寰呭姞瀵嗗瓧绗︿覆
-     */
-    @Override
-    public String decrypt(String value) {
-        return this.sm4.decryptStr(value);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/enumd/AlgorithmType.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/enumd/AlgorithmType.java
deleted file mode 100644
index ff02ecb..0000000
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/enumd/AlgorithmType.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.ruoyi.common.encrypt.enumd;
-
-import com.ruoyi.common.encrypt.core.encryptor.*;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 绠楁硶鍚嶇О
- *
- * @author 鑰侀┈
- * @version 4.6.0
- */
-@Getter
-@AllArgsConstructor
-public enum AlgorithmType {
-
-    /**
-     * 榛樿璧皔ml閰嶇疆
-     */
-    DEFAULT(null),
-
-    /**
-     * base64
-     */
-    BASE64(Base64Encryptor.class),
-
-    /**
-     * aes
-     */
-    AES(AesEncryptor.class),
-
-    /**
-     * rsa
-     */
-    RSA(RsaEncryptor.class),
-
-    /**
-     * sm2
-     */
-    SM2(Sm2Encryptor.class),
-
-    /**
-     * sm4
-     */
-    SM4(Sm4Encryptor.class);
-
-    private final Class<? extends AbstractEncryptor> clazz;
-}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/enumd/EncodeType.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/enumd/EncodeType.java
deleted file mode 100644
index f8d5499..0000000
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/enumd/EncodeType.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.ruoyi.common.encrypt.enumd;
-
-/**
- * 缂栫爜绫诲瀷
- *
- * @author 鑰侀┈
- * @version 4.6.0
- */
-public enum EncodeType {
-
-    /**
-     * 榛樿浣跨敤yml閰嶇疆
-     */
-    DEFAULT,
-
-    /**
-     * base64缂栫爜
-     */
-    BASE64,
-
-    /**
-     * 16杩涘埗缂栫爜
-     */
-    HEX;
-
-}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/interceptor/MybatisDecryptInterceptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/interceptor/MybatisDecryptInterceptor.java
deleted file mode 100644
index 2c209b4..0000000
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/interceptor/MybatisDecryptInterceptor.java
+++ /dev/null
@@ -1,112 +0,0 @@
-package com.ruoyi.common.encrypt.interceptor;
-
-import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.util.ObjectUtil;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.encrypt.annotation.EncryptField;
-import com.ruoyi.common.encrypt.core.EncryptContext;
-import com.ruoyi.common.encrypt.core.EncryptorManager;
-import com.ruoyi.common.encrypt.enumd.AlgorithmType;
-import com.ruoyi.common.encrypt.enumd.EncodeType;
-import com.ruoyi.common.encrypt.properties.EncryptorProperties;
-import lombok.AllArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.ibatis.executor.resultset.ResultSetHandler;
-import org.apache.ibatis.plugin.*;
-
-import java.lang.reflect.Field;
-import java.sql.Statement;
-import java.util.*;
-
-/**
- * 鍑哄弬瑙e瘑鎷︽埅鍣�
- *
- * @author 鑰侀┈
- * @version 4.6.0
- */
-@Slf4j
-@Intercepts({@Signature(
-    type = ResultSetHandler.class,
-    method = "handleResultSets",
-    args = {Statement.class})
-})
-@AllArgsConstructor
-public class MybatisDecryptInterceptor implements Interceptor {
-
-    private final EncryptorManager encryptorManager;
-    private final EncryptorProperties defaultProperties;
-
-    @Override
-    public Object intercept(Invocation invocation) throws Throwable {
-        // 鑾峰彇鎵цmysql鎵ц缁撴灉
-        Object result = invocation.proceed();
-        if (result == null) {
-            return null;
-        }
-        decryptHandler(result);
-        return result;
-    }
-
-    /**
-     * 瑙e瘑瀵硅薄
-     *
-     * @param sourceObject 寰呭姞瀵嗗璞�
-     */
-    private void decryptHandler(Object sourceObject) {
-        if (ObjectUtil.isNull(sourceObject)) {
-            return;
-        }
-        if (sourceObject instanceof Map<?, ?> map) {
-            new HashSet<>(map.values()).forEach(this::decryptHandler);
-            return;
-        }
-        if (sourceObject instanceof List<?> list) {
-            if(CollectionUtil.isEmpty(list)) {
-                return;
-            }
-            // 鍒ゆ柇绗竴涓厓绱犳槸鍚﹀惈鏈夋敞瑙c�傚鏋滄病鏈夌洿鎺ヨ繑鍥烇紝鎻愰珮鏁堢巼
-            Object firstItem = list.get(0);
-            if (CollectionUtil.isEmpty(encryptorManager.getFieldCache(firstItem.getClass()))) {
-                return;
-            }
-            list.forEach(this::decryptHandler);
-            return;
-        }
-        Set<Field> fields = encryptorManager.getFieldCache(sourceObject.getClass());
-        try {
-            for (Field field : fields) {
-                field.set(sourceObject, this.decryptField(String.valueOf(field.get(sourceObject)), field));
-            }
-        } catch (Exception e) {
-            log.error("澶勭悊瑙e瘑瀛楁鏃跺嚭閿�", e);
-        }
-    }
-
-    /**
-     * 瀛楁鍊艰繘琛屽姞瀵嗐�傞�氳繃瀛楁鐨勬壒娉ㄦ敞鍐屾柊鐨勫姞瀵嗙畻娉�
-     *
-     * @param value 寰呭姞瀵嗙殑鍊�
-     * @param field 寰呭姞瀵嗗瓧娈�
-     * @return 鍔犲瘑鍚庣粨鏋�
-     */
-    private String decryptField(String value, Field field) {
-        EncryptField encryptField = field.getAnnotation(EncryptField.class);
-        EncryptContext encryptContext = new EncryptContext();
-        encryptContext.setAlgorithm(encryptField.algorithm() == AlgorithmType.DEFAULT ? defaultProperties.getAlgorithm() : encryptField.algorithm());
-        encryptContext.setEncode(encryptField.encode() == EncodeType.DEFAULT ? defaultProperties.getEncode() : encryptField.encode());
-        encryptContext.setPassword(StringUtils.isBlank(encryptField.password()) ? defaultProperties.getPassword() : encryptField.password());
-        encryptContext.setPrivateKey(StringUtils.isBlank(encryptField.privateKey()) ? defaultProperties.getPrivateKey() : encryptField.privateKey());
-        encryptContext.setPublicKey(StringUtils.isBlank(encryptField.publicKey()) ? defaultProperties.getPublicKey() : encryptField.publicKey());
-        return this.encryptorManager.decrypt(value, encryptContext);
-    }
-
-    @Override
-    public Object plugin(Object target) {
-        return Plugin.wrap(target, this);
-    }
-
-    @Override
-    public void setProperties(Properties properties) {
-
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/interceptor/MybatisEncryptInterceptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/interceptor/MybatisEncryptInterceptor.java
deleted file mode 100644
index 2a0b560..0000000
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/interceptor/MybatisEncryptInterceptor.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package com.ruoyi.common.encrypt.interceptor;
-
-import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.util.ObjectUtil;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.encrypt.annotation.EncryptField;
-import com.ruoyi.common.encrypt.core.EncryptContext;
-import com.ruoyi.common.encrypt.core.EncryptorManager;
-import com.ruoyi.common.encrypt.enumd.AlgorithmType;
-import com.ruoyi.common.encrypt.enumd.EncodeType;
-import com.ruoyi.common.encrypt.properties.EncryptorProperties;
-import lombok.AllArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.ibatis.executor.parameter.ParameterHandler;
-import org.apache.ibatis.plugin.Interceptor;
-import org.apache.ibatis.plugin.Intercepts;
-import org.apache.ibatis.plugin.Invocation;
-import org.apache.ibatis.plugin.Signature;
-
-import java.lang.reflect.Field;
-import java.sql.PreparedStatement;
-import java.util.*;
-
-/**
- * 鍏ュ弬鍔犲瘑鎷︽埅鍣�
- *
- * @author 鑰侀┈
- * @version 4.6.0
- */
-@Slf4j
-@Intercepts({@Signature(
-    type = ParameterHandler.class,
-    method = "setParameters",
-    args = {PreparedStatement.class})
-})
-@AllArgsConstructor
-public class MybatisEncryptInterceptor implements Interceptor {
-
-    private final EncryptorManager encryptorManager;
-    private final EncryptorProperties defaultProperties;
-
-    @Override
-    public Object intercept(Invocation invocation) throws Throwable {
-        return invocation;
-    }
-
-    @Override
-    public Object plugin(Object target) {
-        if (target instanceof ParameterHandler parameterHandler) {
-            // 杩涜鍔犲瘑鎿嶄綔
-            Object parameterObject = parameterHandler.getParameterObject();
-            if (ObjectUtil.isNotNull(parameterObject) && !(parameterObject instanceof String)) {
-                this.encryptHandler(parameterObject);
-            }
-        }
-        return target;
-    }
-
-    /**
-     * 鍔犲瘑瀵硅薄
-     *
-     * @param sourceObject 寰呭姞瀵嗗璞�
-     */
-    private void encryptHandler(Object sourceObject) {
-        if (ObjectUtil.isNull(sourceObject)) {
-            return;
-        }
-        if (sourceObject instanceof Map<?, ?> map) {
-            new HashSet<>(map.values()).forEach(this::encryptHandler);
-            return;
-        }
-        if (sourceObject instanceof List<?> list) {
-            if(CollectionUtil.isEmpty(list)) {
-                return;
-            }
-            // 鍒ゆ柇绗竴涓厓绱犳槸鍚﹀惈鏈夋敞瑙c�傚鏋滄病鏈夌洿鎺ヨ繑鍥烇紝鎻愰珮鏁堢巼
-            Object firstItem = list.get(0);
-            if (CollectionUtil.isEmpty(encryptorManager.getFieldCache(firstItem.getClass()))) {
-                return;
-            }
-            list.forEach(this::encryptHandler);
-            return;
-        }
-        Set<Field> fields = encryptorManager.getFieldCache(sourceObject.getClass());
-        try {
-            for (Field field : fields) {
-                field.set(sourceObject, this.encryptField(String.valueOf(field.get(sourceObject)), field));
-            }
-        } catch (Exception e) {
-            log.error("澶勭悊鍔犲瘑瀛楁鏃跺嚭閿�", e);
-        }
-    }
-
-    /**
-     * 瀛楁鍊艰繘琛屽姞瀵嗐�傞�氳繃瀛楁鐨勬壒娉ㄦ敞鍐屾柊鐨勫姞瀵嗙畻娉�
-     *
-     * @param value 寰呭姞瀵嗙殑鍊�
-     * @param field 寰呭姞瀵嗗瓧娈�
-     * @return 鍔犲瘑鍚庣粨鏋�
-     */
-    private String encryptField(String value, Field field) {
-        EncryptField encryptField = field.getAnnotation(EncryptField.class);
-        EncryptContext encryptContext = new EncryptContext();
-        encryptContext.setAlgorithm(encryptField.algorithm() == AlgorithmType.DEFAULT ? defaultProperties.getAlgorithm() : encryptField.algorithm());
-        encryptContext.setEncode(encryptField.encode() == EncodeType.DEFAULT ? defaultProperties.getEncode() : encryptField.encode());
-        encryptContext.setPassword(StringUtils.isBlank(encryptField.password()) ? defaultProperties.getPassword() : encryptField.password());
-        encryptContext.setPrivateKey(StringUtils.isBlank(encryptField.privateKey()) ? defaultProperties.getPrivateKey() : encryptField.privateKey());
-        encryptContext.setPublicKey(StringUtils.isBlank(encryptField.publicKey()) ? defaultProperties.getPublicKey() : encryptField.publicKey());
-        return this.encryptorManager.encrypt(value, encryptContext);
-    }
-
-
-    @Override
-    public void setProperties(Properties properties) {
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/properties/EncryptorProperties.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/properties/EncryptorProperties.java
deleted file mode 100644
index 003db6c..0000000
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/com/ruoyi/common/encrypt/properties/EncryptorProperties.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.ruoyi.common.encrypt.properties;
-
-import com.ruoyi.common.encrypt.enumd.AlgorithmType;
-import com.ruoyi.common.encrypt.enumd.EncodeType;
-import lombok.Data;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-/**
- * 鍔犺В瀵嗗睘鎬ч厤缃被
- *
- * @author 鑰侀┈
- * @version 4.6.0
- */
-@Data
-@ConfigurationProperties(prefix = "mybatis-encryptor")
-public class EncryptorProperties {
-
-    /**
-     * 杩囨护寮�鍏�
-     */
-    private Boolean enable;
-
-    /**
-     * 榛樿绠楁硶
-     */
-    private AlgorithmType algorithm;
-
-    /**
-     * 瀹夊叏绉橀挜
-     */
-    private String password;
-
-    /**
-     * 鍏挜
-     */
-    private String publicKey;
-
-    /**
-     * 绉侀挜
-     */
-    private String privateKey;
-
-    /**
-     * 缂栫爜鏂瑰紡锛宐ase64/hex
-     */
-    private EncodeType encode;
-
-}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/annotation/EncryptField.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/annotation/EncryptField.java
new file mode 100644
index 0000000..ba0b958
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/annotation/EncryptField.java
@@ -0,0 +1,44 @@
+package org.dromara.common.encrypt.annotation;
+
+import org.dromara.common.encrypt.enumd.AlgorithmType;
+import org.dromara.common.encrypt.enumd.EncodeType;
+
+import java.lang.annotation.*;
+
+/**
+ * 瀛楁鍔犲瘑娉ㄨВ
+ *
+ * @author 鑰侀┈
+ */
+@Documented
+@Inherited
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface EncryptField {
+
+    /**
+     * 鍔犲瘑绠楁硶
+     */
+    AlgorithmType algorithm() default AlgorithmType.DEFAULT;
+
+    /**
+     * 绉橀挜銆侫ES銆丼M4闇�瑕�
+     */
+    String password() default "";
+
+    /**
+     * 鍏挜銆俁SA銆丼M2闇�瑕�
+     */
+    String publicKey() default "";
+
+    /**
+     * 鍏挜銆俁SA銆丼M2闇�瑕�
+     */
+    String privateKey() default "";
+
+    /**
+     * 缂栫爜鏂瑰紡銆傚鍔犲瘑绠楁硶涓築ASE64鐨勪笉璧蜂綔鐢�
+     */
+    EncodeType encode() default EncodeType.DEFAULT;
+
+}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/config/EncryptorAutoConfiguration.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/config/EncryptorAutoConfiguration.java
new file mode 100644
index 0000000..e988a3a
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/config/EncryptorAutoConfiguration.java
@@ -0,0 +1,41 @@
+package org.dromara.common.encrypt.config;
+
+import org.dromara.common.encrypt.core.EncryptorManager;
+import org.dromara.common.encrypt.interceptor.MybatisDecryptInterceptor;
+import org.dromara.common.encrypt.interceptor.MybatisEncryptInterceptor;
+import org.dromara.common.encrypt.properties.EncryptorProperties;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * 鍔犺В瀵嗛厤缃�
+ *
+ * @author 鑰侀┈
+ * @version 4.6.0
+ */
+@AutoConfiguration
+@EnableConfigurationProperties(EncryptorProperties.class)
+@ConditionalOnProperty(value = "mybatis-encryptor.enable", havingValue = "true")
+public class EncryptorAutoConfiguration {
+
+    @Autowired
+    private EncryptorProperties properties;
+
+    @Bean
+    public EncryptorManager encryptorManager() {
+        return new EncryptorManager();
+    }
+
+    @Bean
+    public MybatisEncryptInterceptor mybatisEncryptInterceptor(EncryptorManager encryptorManager) {
+        return new MybatisEncryptInterceptor(encryptorManager, properties);
+    }
+
+    @Bean
+    public MybatisDecryptInterceptor mybatisDecryptInterceptor(EncryptorManager encryptorManager) {
+        return new MybatisDecryptInterceptor(encryptorManager, properties);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/EncryptContext.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/EncryptContext.java
new file mode 100644
index 0000000..2f02eaf
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/EncryptContext.java
@@ -0,0 +1,41 @@
+package org.dromara.common.encrypt.core;
+
+import org.dromara.common.encrypt.enumd.AlgorithmType;
+import org.dromara.common.encrypt.enumd.EncodeType;
+import lombok.Data;
+
+/**
+ * 鍔犲瘑涓婁笅鏂� 鐢ㄤ簬encryptor浼犻�掑繀瑕佺殑鍙傛暟銆�
+ *
+ * @author 鑰侀┈
+ * @version 4.6.0
+ */
+@Data
+public class EncryptContext {
+
+    /**
+     * 榛樿绠楁硶
+     */
+    private AlgorithmType algorithm;
+
+    /**
+     * 瀹夊叏绉橀挜
+     */
+    private String password;
+
+    /**
+     * 鍏挜
+     */
+    private String publicKey;
+
+    /**
+     * 绉侀挜
+     */
+    private String privateKey;
+
+    /**
+     * 缂栫爜鏂瑰紡锛宐ase64/hex
+     */
+    private EncodeType encode;
+
+}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/EncryptorManager.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/EncryptorManager.java
new file mode 100644
index 0000000..07c5675
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/EncryptorManager.java
@@ -0,0 +1,94 @@
+package org.dromara.common.encrypt.core;
+
+import cn.hutool.core.util.ReflectUtil;
+import org.dromara.common.encrypt.annotation.EncryptField;
+import lombok.extern.slf4j.Slf4j;
+
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+
+/**
+ * 鍔犲瘑绠$悊绫�
+ *
+ * @author 鑰侀┈
+ * @version 4.6.0
+ */
+@Slf4j
+public class EncryptorManager {
+
+    /**
+     * 缂撳瓨鍔犲瘑鍣�
+     */
+    Map<EncryptContext, IEncryptor> encryptorMap = new ConcurrentHashMap<>();
+
+    /**
+     * 绫诲姞瀵嗗瓧娈电紦瀛�
+     */
+    Map<Class<?>, Set<Field>> fieldCache = new ConcurrentHashMap<>();
+
+    /**
+     * 鑾峰彇绫诲姞瀵嗗瓧娈电紦瀛�
+     */
+    public Set<Field> getFieldCache(Class<?> sourceClazz) {
+        return fieldCache.computeIfAbsent(sourceClazz, clazz -> {
+            Field[] declaredFields = clazz.getDeclaredFields();
+            Set<Field> fieldSet = Arrays.stream(declaredFields).filter(field ->
+                    field.isAnnotationPresent(EncryptField.class) && field.getType() == String.class)
+                .collect(Collectors.toSet());
+            for (Field field : fieldSet) {
+                field.setAccessible(true);
+            }
+            return fieldSet;
+        });
+    }
+
+    /**
+     * 娉ㄥ唽鍔犲瘑鎵ц鑰呭埌缂撳瓨
+     *
+     * @param encryptContext 鍔犲瘑鎵ц鑰呴渶瑕佺殑鐩稿叧閰嶇疆鍙傛暟
+     */
+    public IEncryptor registAndGetEncryptor(EncryptContext encryptContext) {
+        if (encryptorMap.containsKey(encryptContext)) {
+            return encryptorMap.get(encryptContext);
+        }
+        IEncryptor encryptor = ReflectUtil.newInstance(encryptContext.getAlgorithm().getClazz(), encryptContext);
+        encryptorMap.put(encryptContext, encryptor);
+        return encryptor;
+    }
+
+    /**
+     * 绉婚櫎缂撳瓨涓殑鍔犲瘑鎵ц鑰�
+     *
+     * @param encryptContext 鍔犲瘑鎵ц鑰呴渶瑕佺殑鐩稿叧閰嶇疆鍙傛暟
+     */
+    public void removeEncryptor(EncryptContext encryptContext) {
+        this.encryptorMap.remove(encryptContext);
+    }
+
+    /**
+     * 鏍规嵁閰嶇疆杩涜鍔犲瘑銆備細杩涜鏈湴缂撳瓨瀵瑰簲鐨勭畻娉曞拰瀵瑰簲鐨勭閽ヤ俊鎭��
+     *
+     * @param value          寰呭姞瀵嗙殑鍊�
+     * @param encryptContext 鍔犲瘑鐩稿叧鐨勯厤缃俊鎭�
+     */
+    public String encrypt(String value, EncryptContext encryptContext) {
+        IEncryptor encryptor = this.registAndGetEncryptor(encryptContext);
+        return encryptor.encrypt(value, encryptContext.getEncode());
+    }
+
+    /**
+     * 鏍规嵁閰嶇疆杩涜瑙e瘑
+     *
+     * @param value          寰呰В瀵嗙殑鍊�
+     * @param encryptContext 鍔犲瘑鐩稿叧鐨勯厤缃俊鎭�
+     */
+    public String decrypt(String value, EncryptContext encryptContext) {
+        IEncryptor encryptor = this.registAndGetEncryptor(encryptContext);
+        return encryptor.decrypt(value);
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/IEncryptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/IEncryptor.java
new file mode 100644
index 0000000..dbc4420
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/IEncryptor.java
@@ -0,0 +1,35 @@
+package org.dromara.common.encrypt.core;
+
+import org.dromara.common.encrypt.enumd.AlgorithmType;
+import org.dromara.common.encrypt.enumd.EncodeType;
+
+/**
+ * 鍔犺В鑰�
+ *
+ * @author 鑰侀┈
+ * @version 4.6.0
+ */
+public interface IEncryptor {
+
+    /**
+     * 鑾峰緱褰撳墠绠楁硶
+     */
+    AlgorithmType algorithm();
+
+    /**
+     * 鍔犲瘑
+     *
+     * @param value      寰呭姞瀵嗗瓧绗︿覆
+     * @param encodeType 鍔犲瘑鍚庣殑缂栫爜鏍煎紡
+     * @return 鍔犲瘑鍚庣殑瀛楃涓�
+     */
+    String encrypt(String value, EncodeType encodeType);
+
+    /**
+     * 瑙e瘑
+     *
+     * @param value      寰呭姞瀵嗗瓧绗︿覆
+     * @return 瑙e瘑鍚庣殑瀛楃涓�
+     */
+    String decrypt(String value);
+}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/AbstractEncryptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/AbstractEncryptor.java
new file mode 100644
index 0000000..858d229
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/AbstractEncryptor.java
@@ -0,0 +1,18 @@
+package org.dromara.common.encrypt.core.encryptor;
+
+import org.dromara.common.encrypt.core.EncryptContext;
+import org.dromara.common.encrypt.core.IEncryptor;
+
+/**
+ * 鎵�鏈夊姞瀵嗘墽琛岃�呯殑鍩虹被
+ *
+ * @author 鑰侀┈
+ * @version 4.6.0
+ */
+public abstract class AbstractEncryptor implements IEncryptor {
+
+    public AbstractEncryptor(EncryptContext context) {
+        // 鐢ㄦ埛閰嶇疆鏍¢獙涓庨厤缃敞鍏�
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/AesEncryptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/AesEncryptor.java
new file mode 100644
index 0000000..228a362
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/AesEncryptor.java
@@ -0,0 +1,69 @@
+package org.dromara.common.encrypt.core.encryptor;
+
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.crypto.symmetric.AES;
+import org.dromara.common.encrypt.core.EncryptContext;
+import org.dromara.common.encrypt.enumd.AlgorithmType;
+import org.dromara.common.encrypt.enumd.EncodeType;
+
+import java.nio.charset.StandardCharsets;
+
+/**
+ * AES绠楁硶瀹炵幇
+ *
+ * @author 鑰侀┈
+ * @version 4.6.0
+ */
+public class AesEncryptor extends AbstractEncryptor {
+
+    private final AES aes;
+
+    public AesEncryptor(EncryptContext context) {
+        super(context);
+        String password = context.getPassword();
+        if (StrUtil.isBlank(password)) {
+            throw new IllegalArgumentException("AES娌℃湁鑾峰緱绉橀挜淇℃伅");
+        }
+        // aes绠楁硶鐨勭閽ヨ姹傛槸16浣嶃��24浣嶃��32浣�
+        int[] array = {16, 24, 32};
+        if (!ArrayUtil.contains(array, password.length())) {
+            throw new IllegalArgumentException("AES绉橀挜闀垮害搴旇涓�16浣嶃��24浣嶃��32浣嶏紝瀹為檯涓�" + password.length() + "浣�");
+        }
+        aes = SecureUtil.aes(context.getPassword().getBytes(StandardCharsets.UTF_8));
+    }
+
+    /**
+     * 鑾峰緱褰撳墠绠楁硶
+     */
+    @Override
+    public AlgorithmType algorithm() {
+        return AlgorithmType.AES;
+    }
+
+    /**
+     * 鍔犲瘑
+     *
+     * @param value      寰呭姞瀵嗗瓧绗︿覆
+     * @param encodeType 鍔犲瘑鍚庣殑缂栫爜鏍煎紡
+     */
+    @Override
+    public String encrypt(String value, EncodeType encodeType) {
+        if (encodeType == EncodeType.HEX) {
+            return aes.encryptHex(value);
+        } else {
+            return aes.encryptBase64(value);
+        }
+    }
+
+    /**
+     * 瑙e瘑
+     *
+     * @param value      寰呭姞瀵嗗瓧绗︿覆
+     */
+    @Override
+    public String decrypt(String value) {
+        return this.aes.decryptStr(value);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/Base64Encryptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/Base64Encryptor.java
new file mode 100644
index 0000000..4003954
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/Base64Encryptor.java
@@ -0,0 +1,48 @@
+package org.dromara.common.encrypt.core.encryptor;
+
+import cn.hutool.core.codec.Base64;
+import org.dromara.common.encrypt.core.EncryptContext;
+import org.dromara.common.encrypt.enumd.AlgorithmType;
+import org.dromara.common.encrypt.enumd.EncodeType;
+
+/**
+ * Base64绠楁硶瀹炵幇
+ *
+ * @author 鑰侀┈
+ * @version 4.6.0
+ */
+public class Base64Encryptor extends AbstractEncryptor {
+
+    public Base64Encryptor(EncryptContext context) {
+        super(context);
+    }
+
+    /**
+     * 鑾峰緱褰撳墠绠楁硶
+     */
+    @Override
+    public AlgorithmType algorithm() {
+        return AlgorithmType.BASE64;
+    }
+
+    /**
+     * 鍔犲瘑
+     *
+     * @param value      寰呭姞瀵嗗瓧绗︿覆
+     * @param encodeType 鍔犲瘑鍚庣殑缂栫爜鏍煎紡
+     */
+    @Override
+    public String encrypt(String value, EncodeType encodeType) {
+        return Base64.encode(value);
+    }
+
+    /**
+     * 瑙e瘑
+     *
+     * @param value      寰呭姞瀵嗗瓧绗︿覆
+     */
+    @Override
+    public String decrypt(String value) {
+        return Base64.decodeStr(value);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/RsaEncryptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/RsaEncryptor.java
new file mode 100644
index 0000000..61b1dff
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/RsaEncryptor.java
@@ -0,0 +1,65 @@
+package org.dromara.common.encrypt.core.encryptor;
+
+import cn.hutool.core.codec.Base64;
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.crypto.asymmetric.KeyType;
+import cn.hutool.crypto.asymmetric.RSA;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.encrypt.core.EncryptContext;
+import org.dromara.common.encrypt.enumd.AlgorithmType;
+import org.dromara.common.encrypt.enumd.EncodeType;
+
+
+/**
+ * RSA绠楁硶瀹炵幇
+ *
+ * @author 鑰侀┈
+ * @version 4.6.0
+ */
+public class RsaEncryptor extends AbstractEncryptor {
+
+    private final RSA rsa;
+
+    public RsaEncryptor(EncryptContext context) {
+        super(context);
+        String privateKey = context.getPrivateKey();
+        String publicKey = context.getPublicKey();
+        if (StringUtils.isAnyEmpty(privateKey, publicKey)) {
+            throw new IllegalArgumentException("RSA鍏閽ュ潎闇�瑕佹彁渚涳紝鍏挜鍔犲瘑锛岀閽ヨВ瀵嗐��");
+        }
+        this.rsa = SecureUtil.rsa(Base64.decode(privateKey), Base64.decode(publicKey));
+    }
+
+    /**
+     * 鑾峰緱褰撳墠绠楁硶
+     */
+    @Override
+    public AlgorithmType algorithm() {
+        return AlgorithmType.RSA;
+    }
+
+    /**
+     * 鍔犲瘑
+     *
+     * @param value      寰呭姞瀵嗗瓧绗︿覆
+     * @param encodeType 鍔犲瘑鍚庣殑缂栫爜鏍煎紡
+     */
+    @Override
+    public String encrypt(String value, EncodeType encodeType) {
+        if (encodeType == EncodeType.HEX) {
+            return rsa.encryptHex(value, KeyType.PublicKey);
+        } else {
+            return rsa.encryptBase64(value, KeyType.PublicKey);
+        }
+    }
+
+    /**
+     * 瑙e瘑
+     *
+     * @param value      寰呭姞瀵嗗瓧绗︿覆
+     */
+    @Override
+    public String decrypt(String value) {
+        return this.rsa.decryptStr(value, KeyType.PrivateKey);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/Sm2Encryptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/Sm2Encryptor.java
new file mode 100644
index 0000000..c728cf8
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/Sm2Encryptor.java
@@ -0,0 +1,64 @@
+package org.dromara.common.encrypt.core.encryptor;
+
+import cn.hutool.core.codec.Base64;
+import cn.hutool.crypto.SmUtil;
+import cn.hutool.crypto.asymmetric.KeyType;
+import cn.hutool.crypto.asymmetric.SM2;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.encrypt.core.EncryptContext;
+import org.dromara.common.encrypt.enumd.AlgorithmType;
+import org.dromara.common.encrypt.enumd.EncodeType;
+
+/**
+ * sm2绠楁硶瀹炵幇
+ *
+ * @author 鑰侀┈
+ * @version 4.6.0
+ */
+public class Sm2Encryptor extends AbstractEncryptor {
+
+    private final SM2 sm2;
+
+    public Sm2Encryptor(EncryptContext context) {
+        super(context);
+        String privateKey = context.getPrivateKey();
+        String publicKey = context.getPublicKey();
+        if (StringUtils.isAnyEmpty(privateKey, publicKey)) {
+            throw new IllegalArgumentException("SM2鍏閽ュ潎闇�瑕佹彁渚涳紝鍏挜鍔犲瘑锛岀閽ヨВ瀵嗐��");
+        }
+        this.sm2 = SmUtil.sm2(Base64.decode(privateKey), Base64.decode(publicKey));
+    }
+
+    /**
+     * 鑾峰緱褰撳墠绠楁硶
+     */
+    @Override
+    public AlgorithmType algorithm() {
+        return AlgorithmType.SM2;
+    }
+
+    /**
+     * 鍔犲瘑
+     *
+     * @param value      寰呭姞瀵嗗瓧绗︿覆
+     * @param encodeType 鍔犲瘑鍚庣殑缂栫爜鏍煎紡
+     */
+    @Override
+    public String encrypt(String value, EncodeType encodeType) {
+        if (encodeType == EncodeType.HEX) {
+            return sm2.encryptHex(value, KeyType.PublicKey);
+        } else {
+            return sm2.encryptBase64(value, KeyType.PublicKey);
+        }
+    }
+
+    /**
+     * 瑙e瘑
+     *
+     * @param value      寰呭姞瀵嗗瓧绗︿覆
+     */
+    @Override
+    public String decrypt(String value) {
+        return this.sm2.decryptStr(value, KeyType.PrivateKey);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/Sm4Encryptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/Sm4Encryptor.java
new file mode 100644
index 0000000..2a32faf
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/Sm4Encryptor.java
@@ -0,0 +1,67 @@
+package org.dromara.common.encrypt.core.encryptor;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.SmUtil;
+import cn.hutool.crypto.symmetric.SM4;
+import org.dromara.common.encrypt.core.EncryptContext;
+import org.dromara.common.encrypt.enumd.AlgorithmType;
+import org.dromara.common.encrypt.enumd.EncodeType;
+
+import java.nio.charset.StandardCharsets;
+
+/**
+ * sm4绠楁硶瀹炵幇
+ *
+ * @author 鑰侀┈
+ * @version 4.6.0
+ */
+public class Sm4Encryptor extends AbstractEncryptor {
+
+    private final SM4 sm4;
+
+    public Sm4Encryptor(EncryptContext context) {
+        super(context);
+        String password = context.getPassword();
+        if (StrUtil.isBlank(password)) {
+            throw new IllegalArgumentException("SM4娌℃湁鑾峰緱绉橀挜淇℃伅");
+        }
+        // sm4绠楁硶鐨勭閽ヨ姹傛槸16浣嶉暱搴�
+        if (16 != password.length()) {
+            throw new IllegalArgumentException("SM4绉橀挜闀垮害搴旇涓�16浣嶏紝瀹為檯涓�" + password.length() + "浣�");
+        }
+        this.sm4 = SmUtil.sm4(password.getBytes(StandardCharsets.UTF_8));
+    }
+
+    /**
+     * 鑾峰緱褰撳墠绠楁硶
+     */
+    @Override
+    public AlgorithmType algorithm() {
+        return AlgorithmType.SM4;
+    }
+
+    /**
+     * 鍔犲瘑
+     *
+     * @param value      寰呭姞瀵嗗瓧绗︿覆
+     * @param encodeType 鍔犲瘑鍚庣殑缂栫爜鏍煎紡
+     */
+    @Override
+    public String encrypt(String value, EncodeType encodeType) {
+        if (encodeType == EncodeType.HEX) {
+            return sm4.encryptHex(value);
+        } else {
+            return sm4.encryptBase64(value);
+        }
+    }
+
+    /**
+     * 瑙e瘑
+     *
+     * @param value      寰呭姞瀵嗗瓧绗︿覆
+     */
+    @Override
+    public String decrypt(String value) {
+        return this.sm4.decryptStr(value);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/enumd/AlgorithmType.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/enumd/AlgorithmType.java
new file mode 100644
index 0000000..26ee1ee
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/enumd/AlgorithmType.java
@@ -0,0 +1,48 @@
+package org.dromara.common.encrypt.enumd;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.dromara.common.encrypt.core.encryptor.*;
+
+/**
+ * 绠楁硶鍚嶇О
+ *
+ * @author 鑰侀┈
+ * @version 4.6.0
+ */
+@Getter
+@AllArgsConstructor
+public enum AlgorithmType {
+
+    /**
+     * 榛樿璧皔ml閰嶇疆
+     */
+    DEFAULT(null),
+
+    /**
+     * base64
+     */
+    BASE64(Base64Encryptor.class),
+
+    /**
+     * aes
+     */
+    AES(AesEncryptor.class),
+
+    /**
+     * rsa
+     */
+    RSA(RsaEncryptor.class),
+
+    /**
+     * sm2
+     */
+    SM2(Sm2Encryptor.class),
+
+    /**
+     * sm4
+     */
+    SM4(Sm4Encryptor.class);
+
+    private final Class<? extends AbstractEncryptor> clazz;
+}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/enumd/EncodeType.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/enumd/EncodeType.java
new file mode 100644
index 0000000..f471221
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/enumd/EncodeType.java
@@ -0,0 +1,26 @@
+package org.dromara.common.encrypt.enumd;
+
+/**
+ * 缂栫爜绫诲瀷
+ *
+ * @author 鑰侀┈
+ * @version 4.6.0
+ */
+public enum EncodeType {
+
+    /**
+     * 榛樿浣跨敤yml閰嶇疆
+     */
+    DEFAULT,
+
+    /**
+     * base64缂栫爜
+     */
+    BASE64,
+
+    /**
+     * 16杩涘埗缂栫爜
+     */
+    HEX;
+
+}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisDecryptInterceptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisDecryptInterceptor.java
new file mode 100644
index 0000000..6d27ed6
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisDecryptInterceptor.java
@@ -0,0 +1,112 @@
+package org.dromara.common.encrypt.interceptor;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.ObjectUtil;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.encrypt.annotation.EncryptField;
+import org.dromara.common.encrypt.core.EncryptContext;
+import org.dromara.common.encrypt.core.EncryptorManager;
+import org.dromara.common.encrypt.enumd.AlgorithmType;
+import org.dromara.common.encrypt.enumd.EncodeType;
+import org.dromara.common.encrypt.properties.EncryptorProperties;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.executor.resultset.ResultSetHandler;
+import org.apache.ibatis.plugin.*;
+
+import java.lang.reflect.Field;
+import java.sql.Statement;
+import java.util.*;
+
+/**
+ * 鍑哄弬瑙e瘑鎷︽埅鍣�
+ *
+ * @author 鑰侀┈
+ * @version 4.6.0
+ */
+@Slf4j
+@Intercepts({@Signature(
+    type = ResultSetHandler.class,
+    method = "handleResultSets",
+    args = {Statement.class})
+})
+@AllArgsConstructor
+public class MybatisDecryptInterceptor implements Interceptor {
+
+    private final EncryptorManager encryptorManager;
+    private final EncryptorProperties defaultProperties;
+
+    @Override
+    public Object intercept(Invocation invocation) throws Throwable {
+        // 鑾峰彇鎵цmysql鎵ц缁撴灉
+        Object result = invocation.proceed();
+        if (result == null) {
+            return null;
+        }
+        decryptHandler(result);
+        return result;
+    }
+
+    /**
+     * 瑙e瘑瀵硅薄
+     *
+     * @param sourceObject 寰呭姞瀵嗗璞�
+     */
+    private void decryptHandler(Object sourceObject) {
+        if (ObjectUtil.isNull(sourceObject)) {
+            return;
+        }
+        if (sourceObject instanceof Map<?, ?> map) {
+            new HashSet<>(map.values()).forEach(this::decryptHandler);
+            return;
+        }
+        if (sourceObject instanceof List<?> list) {
+            if(CollectionUtil.isEmpty(list)) {
+                return;
+            }
+            // 鍒ゆ柇绗竴涓厓绱犳槸鍚﹀惈鏈夋敞瑙c�傚鏋滄病鏈夌洿鎺ヨ繑鍥烇紝鎻愰珮鏁堢巼
+            Object firstItem = list.get(0);
+            if (CollectionUtil.isEmpty(encryptorManager.getFieldCache(firstItem.getClass()))) {
+                return;
+            }
+            list.forEach(this::decryptHandler);
+            return;
+        }
+        Set<Field> fields = encryptorManager.getFieldCache(sourceObject.getClass());
+        try {
+            for (Field field : fields) {
+                field.set(sourceObject, this.decryptField(String.valueOf(field.get(sourceObject)), field));
+            }
+        } catch (Exception e) {
+            log.error("澶勭悊瑙e瘑瀛楁鏃跺嚭閿�", e);
+        }
+    }
+
+    /**
+     * 瀛楁鍊艰繘琛屽姞瀵嗐�傞�氳繃瀛楁鐨勬壒娉ㄦ敞鍐屾柊鐨勫姞瀵嗙畻娉�
+     *
+     * @param value 寰呭姞瀵嗙殑鍊�
+     * @param field 寰呭姞瀵嗗瓧娈�
+     * @return 鍔犲瘑鍚庣粨鏋�
+     */
+    private String decryptField(String value, Field field) {
+        EncryptField encryptField = field.getAnnotation(EncryptField.class);
+        EncryptContext encryptContext = new EncryptContext();
+        encryptContext.setAlgorithm(encryptField.algorithm() == AlgorithmType.DEFAULT ? defaultProperties.getAlgorithm() : encryptField.algorithm());
+        encryptContext.setEncode(encryptField.encode() == EncodeType.DEFAULT ? defaultProperties.getEncode() : encryptField.encode());
+        encryptContext.setPassword(StringUtils.isBlank(encryptField.password()) ? defaultProperties.getPassword() : encryptField.password());
+        encryptContext.setPrivateKey(StringUtils.isBlank(encryptField.privateKey()) ? defaultProperties.getPrivateKey() : encryptField.privateKey());
+        encryptContext.setPublicKey(StringUtils.isBlank(encryptField.publicKey()) ? defaultProperties.getPublicKey() : encryptField.publicKey());
+        return this.encryptorManager.decrypt(value, encryptContext);
+    }
+
+    @Override
+    public Object plugin(Object target) {
+        return Plugin.wrap(target, this);
+    }
+
+    @Override
+    public void setProperties(Properties properties) {
+
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisEncryptInterceptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisEncryptInterceptor.java
new file mode 100644
index 0000000..cf2becb
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisEncryptInterceptor.java
@@ -0,0 +1,116 @@
+package org.dromara.common.encrypt.interceptor;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.ObjectUtil;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.encrypt.annotation.EncryptField;
+import org.dromara.common.encrypt.core.EncryptContext;
+import org.dromara.common.encrypt.core.EncryptorManager;
+import org.dromara.common.encrypt.enumd.AlgorithmType;
+import org.dromara.common.encrypt.enumd.EncodeType;
+import org.dromara.common.encrypt.properties.EncryptorProperties;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.executor.parameter.ParameterHandler;
+import org.apache.ibatis.plugin.Interceptor;
+import org.apache.ibatis.plugin.Intercepts;
+import org.apache.ibatis.plugin.Invocation;
+import org.apache.ibatis.plugin.Signature;
+
+import java.lang.reflect.Field;
+import java.sql.PreparedStatement;
+import java.util.*;
+
+/**
+ * 鍏ュ弬鍔犲瘑鎷︽埅鍣�
+ *
+ * @author 鑰侀┈
+ * @version 4.6.0
+ */
+@Slf4j
+@Intercepts({@Signature(
+    type = ParameterHandler.class,
+    method = "setParameters",
+    args = {PreparedStatement.class})
+})
+@AllArgsConstructor
+public class MybatisEncryptInterceptor implements Interceptor {
+
+    private final EncryptorManager encryptorManager;
+    private final EncryptorProperties defaultProperties;
+
+    @Override
+    public Object intercept(Invocation invocation) throws Throwable {
+        return invocation;
+    }
+
+    @Override
+    public Object plugin(Object target) {
+        if (target instanceof ParameterHandler parameterHandler) {
+            // 杩涜鍔犲瘑鎿嶄綔
+            Object parameterObject = parameterHandler.getParameterObject();
+            if (ObjectUtil.isNotNull(parameterObject) && !(parameterObject instanceof String)) {
+                this.encryptHandler(parameterObject);
+            }
+        }
+        return target;
+    }
+
+    /**
+     * 鍔犲瘑瀵硅薄
+     *
+     * @param sourceObject 寰呭姞瀵嗗璞�
+     */
+    private void encryptHandler(Object sourceObject) {
+        if (ObjectUtil.isNull(sourceObject)) {
+            return;
+        }
+        if (sourceObject instanceof Map<?, ?> map) {
+            new HashSet<>(map.values()).forEach(this::encryptHandler);
+            return;
+        }
+        if (sourceObject instanceof List<?> list) {
+            if(CollectionUtil.isEmpty(list)) {
+                return;
+            }
+            // 鍒ゆ柇绗竴涓厓绱犳槸鍚﹀惈鏈夋敞瑙c�傚鏋滄病鏈夌洿鎺ヨ繑鍥烇紝鎻愰珮鏁堢巼
+            Object firstItem = list.get(0);
+            if (CollectionUtil.isEmpty(encryptorManager.getFieldCache(firstItem.getClass()))) {
+                return;
+            }
+            list.forEach(this::encryptHandler);
+            return;
+        }
+        Set<Field> fields = encryptorManager.getFieldCache(sourceObject.getClass());
+        try {
+            for (Field field : fields) {
+                field.set(sourceObject, this.encryptField(String.valueOf(field.get(sourceObject)), field));
+            }
+        } catch (Exception e) {
+            log.error("澶勭悊鍔犲瘑瀛楁鏃跺嚭閿�", e);
+        }
+    }
+
+    /**
+     * 瀛楁鍊艰繘琛屽姞瀵嗐�傞�氳繃瀛楁鐨勬壒娉ㄦ敞鍐屾柊鐨勫姞瀵嗙畻娉�
+     *
+     * @param value 寰呭姞瀵嗙殑鍊�
+     * @param field 寰呭姞瀵嗗瓧娈�
+     * @return 鍔犲瘑鍚庣粨鏋�
+     */
+    private String encryptField(String value, Field field) {
+        EncryptField encryptField = field.getAnnotation(EncryptField.class);
+        EncryptContext encryptContext = new EncryptContext();
+        encryptContext.setAlgorithm(encryptField.algorithm() == AlgorithmType.DEFAULT ? defaultProperties.getAlgorithm() : encryptField.algorithm());
+        encryptContext.setEncode(encryptField.encode() == EncodeType.DEFAULT ? defaultProperties.getEncode() : encryptField.encode());
+        encryptContext.setPassword(StringUtils.isBlank(encryptField.password()) ? defaultProperties.getPassword() : encryptField.password());
+        encryptContext.setPrivateKey(StringUtils.isBlank(encryptField.privateKey()) ? defaultProperties.getPrivateKey() : encryptField.privateKey());
+        encryptContext.setPublicKey(StringUtils.isBlank(encryptField.publicKey()) ? defaultProperties.getPublicKey() : encryptField.publicKey());
+        return this.encryptorManager.encrypt(value, encryptContext);
+    }
+
+
+    @Override
+    public void setProperties(Properties properties) {
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/properties/EncryptorProperties.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/properties/EncryptorProperties.java
new file mode 100644
index 0000000..ba445c1
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/properties/EncryptorProperties.java
@@ -0,0 +1,48 @@
+package org.dromara.common.encrypt.properties;
+
+import org.dromara.common.encrypt.enumd.AlgorithmType;
+import org.dromara.common.encrypt.enumd.EncodeType;
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * 鍔犺В瀵嗗睘鎬ч厤缃被
+ *
+ * @author 鑰侀┈
+ * @version 4.6.0
+ */
+@Data
+@ConfigurationProperties(prefix = "mybatis-encryptor")
+public class EncryptorProperties {
+
+    /**
+     * 杩囨护寮�鍏�
+     */
+    private Boolean enable;
+
+    /**
+     * 榛樿绠楁硶
+     */
+    private AlgorithmType algorithm;
+
+    /**
+     * 瀹夊叏绉橀挜
+     */
+    private String password;
+
+    /**
+     * 鍏挜
+     */
+    private String publicKey;
+
+    /**
+     * 绉侀挜
+     */
+    private String privateKey;
+
+    /**
+     * 缂栫爜鏂瑰紡锛宐ase64/hex
+     */
+    private EncodeType encode;
+
+}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-encrypt/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index e1063e2..fe37589 100644
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +1 @@
-com.ruoyi.common.encrypt.config.EncryptorAutoConfiguration
+org.dromara.common.encrypt.config.EncryptorAutoConfiguration
diff --git a/ruoyi-common/ruoyi-common-excel/pom.xml b/ruoyi-common/ruoyi-common-excel/pom.xml
index 3792cbc..1b687e4 100644
--- a/ruoyi-common/ruoyi-common-excel/pom.xml
+++ b/ruoyi-common/ruoyi-common-excel/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-common</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -18,7 +18,7 @@
 
     <dependencies>
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-json</artifactId>
         </dependency>
 
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/annotation/CellMerge.java b/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/annotation/CellMerge.java
deleted file mode 100644
index 5c0f552..0000000
--- a/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/annotation/CellMerge.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.ruoyi.common.excel.annotation;
-
-import com.ruoyi.common.excel.core.CellMergeStrategy;
-
-import java.lang.annotation.*;
-
-/**
- * excel 鍒楀崟鍏冩牸鍚堝苟(鍚堝苟鍒楃浉鍚岄」)
- *
- * 闇�鎼厤 {@link CellMergeStrategy} 绛栫暐浣跨敤
- *
- * @author Lion Li
- */
-@Target(ElementType.FIELD)
-@Retention(RetentionPolicy.RUNTIME)
-@Inherited
-public @interface CellMerge {
-
-	/**
-	 * col index
-	 */
-	int index() default -1;
-
-}
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/annotation/ExcelDictFormat.java b/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/annotation/ExcelDictFormat.java
deleted file mode 100644
index 162dc79..0000000
--- a/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/annotation/ExcelDictFormat.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.ruoyi.common.excel.annotation;
-
-import com.ruoyi.common.core.utils.StringUtils;
-
-import java.lang.annotation.*;
-
-/**
- * 瀛楀吀鏍煎紡鍖�
- *
- * @author Lion Li
- */
-@Target({ElementType.FIELD})
-@Retention(RetentionPolicy.RUNTIME)
-@Inherited
-public @interface ExcelDictFormat {
-
-    /**
-     * 濡傛灉鏄瓧鍏哥被鍨嬶紝璇疯缃瓧鍏哥殑type鍊� (濡�: sys_user_sex)
-     */
-    String dictType() default "";
-
-    /**
-     * 璇诲彇鍐呭杞〃杈惧紡 (濡�: 0=鐢�,1=濂�,2=鏈煡)
-     */
-    String readConverterExp() default "";
-
-    /**
-     * 鍒嗛殧绗︼紝璇诲彇瀛楃涓茬粍鍐呭
-     */
-    String separator() default StringUtils.SEPARATOR;
-
-}
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/annotation/ExcelEnumFormat.java b/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/annotation/ExcelEnumFormat.java
deleted file mode 100644
index d5fda7c..0000000
--- a/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/annotation/ExcelEnumFormat.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.ruoyi.common.excel.annotation;
-
-import java.lang.annotation.*;
-
-/**
- * 鏋氫妇鏍煎紡鍖�
- *
- * @author Liang
- */
-@Target({ElementType.FIELD})
-@Retention(RetentionPolicy.RUNTIME)
-@Inherited
-public @interface ExcelEnumFormat {
-
-    /**
-     * 瀛楀吀鏋氫妇绫诲瀷
-     */
-    Class<? extends Enum<?>> enumClass();
-
-    /**
-     * 瀛楀吀鏋氫妇绫讳腑瀵瑰簲鐨刢ode灞炴�у悕绉帮紝榛樿涓篶ode
-     */
-    String codeField() default "code";
-
-    /**
-     * 瀛楀吀鏋氫妇绫讳腑瀵瑰簲鐨則ext灞炴�у悕绉帮紝榛樿涓簍ext
-     */
-    String textField() default "text";
-
-}
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/convert/ExcelBigNumberConvert.java b/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/convert/ExcelBigNumberConvert.java
deleted file mode 100644
index 1e10334..0000000
--- a/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/convert/ExcelBigNumberConvert.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.ruoyi.common.excel.convert;
-
-import cn.hutool.core.convert.Convert;
-import cn.hutool.core.util.ObjectUtil;
-import com.alibaba.excel.converters.Converter;
-import com.alibaba.excel.enums.CellDataTypeEnum;
-import com.alibaba.excel.metadata.GlobalConfiguration;
-import com.alibaba.excel.metadata.data.ReadCellData;
-import com.alibaba.excel.metadata.data.WriteCellData;
-import com.alibaba.excel.metadata.property.ExcelContentProperty;
-import lombok.extern.slf4j.Slf4j;
-
-import java.math.BigDecimal;
-
-/**
- * 澶ф暟鍊艰浆鎹�
- * Excel 鏁板�奸暱搴︿綅15浣� 澶т簬15浣嶇殑鏁板�艰浆鎹綅瀛楃涓�
- *
- * @author Lion Li
- */
-@Slf4j
-public class ExcelBigNumberConvert implements Converter<Long> {
-
-    @Override
-    public Class<Long> supportJavaTypeKey() {
-        return Long.class;
-    }
-
-    @Override
-    public CellDataTypeEnum supportExcelTypeKey() {
-        return CellDataTypeEnum.STRING;
-    }
-
-    @Override
-    public Long convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
-        return Convert.toLong(cellData.getData());
-    }
-
-    @Override
-    public WriteCellData<Object> convertToExcelData(Long object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
-        if (ObjectUtil.isNotNull(object)) {
-            String str = Convert.toStr(object);
-            if (str.length() > 15) {
-                return new WriteCellData<>(str);
-            }
-        }
-        WriteCellData<Object> cellData = new WriteCellData<>(new BigDecimal(object));
-        cellData.setType(CellDataTypeEnum.NUMBER);
-        return cellData;
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/convert/ExcelDictConvert.java b/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/convert/ExcelDictConvert.java
deleted file mode 100644
index 43af5ee..0000000
--- a/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/convert/ExcelDictConvert.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.ruoyi.common.excel.convert;
-
-import cn.hutool.core.annotation.AnnotationUtil;
-import cn.hutool.core.convert.Convert;
-import cn.hutool.core.util.ObjectUtil;
-import com.alibaba.excel.converters.Converter;
-import com.alibaba.excel.enums.CellDataTypeEnum;
-import com.alibaba.excel.metadata.GlobalConfiguration;
-import com.alibaba.excel.metadata.data.ReadCellData;
-import com.alibaba.excel.metadata.data.WriteCellData;
-import com.alibaba.excel.metadata.property.ExcelContentProperty;
-import com.ruoyi.common.excel.annotation.ExcelDictFormat;
-import com.ruoyi.common.core.service.DictService;
-import com.ruoyi.common.core.utils.SpringUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.excel.utils.ExcelUtil;
-import lombok.extern.slf4j.Slf4j;
-
-import java.lang.reflect.Field;
-
-/**
- * 瀛楀吀鏍煎紡鍖栬浆鎹㈠鐞�
- *
- * @author Lion Li
- */
-@Slf4j
-public class ExcelDictConvert implements Converter<Object> {
-
-    @Override
-    public Class<Object> supportJavaTypeKey() {
-        return Object.class;
-    }
-
-    @Override
-    public CellDataTypeEnum supportExcelTypeKey() {
-        return null;
-    }
-
-    @Override
-    public Object convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
-        ExcelDictFormat anno = getAnnotation(contentProperty.getField());
-        String type = anno.dictType();
-        String label = cellData.getStringValue();
-        String value;
-        if (StringUtils.isBlank(type)) {
-            value = ExcelUtil.reverseByExp(label, anno.readConverterExp(), anno.separator());
-        } else {
-            value = SpringUtils.getBean(DictService.class).getDictValue(type, label, anno.separator());
-        }
-        return Convert.convert(contentProperty.getField().getType(), value);
-    }
-
-    @Override
-    public WriteCellData<String> convertToExcelData(Object object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
-        if (ObjectUtil.isNull(object)) {
-            return new WriteCellData<>("");
-        }
-        ExcelDictFormat anno = getAnnotation(contentProperty.getField());
-        String type = anno.dictType();
-        String value = Convert.toStr(object);
-        String label;
-        if (StringUtils.isBlank(type)) {
-            label = ExcelUtil.convertByExp(value, anno.readConverterExp(), anno.separator());
-        } else {
-            label = SpringUtils.getBean(DictService.class).getDictLabel(type, value, anno.separator());
-        }
-        return new WriteCellData<>(label);
-    }
-
-    private ExcelDictFormat getAnnotation(Field field) {
-        return AnnotationUtil.getAnnotation(field, ExcelDictFormat.class);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/convert/ExcelEnumConvert.java b/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/convert/ExcelEnumConvert.java
deleted file mode 100644
index 804f9f0..0000000
--- a/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/convert/ExcelEnumConvert.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package com.ruoyi.common.excel.convert;
-
-import cn.hutool.core.annotation.AnnotationUtil;
-import cn.hutool.core.convert.Convert;
-import cn.hutool.core.util.ObjectUtil;
-import com.alibaba.excel.converters.Converter;
-import com.alibaba.excel.enums.CellDataTypeEnum;
-import com.alibaba.excel.metadata.GlobalConfiguration;
-import com.alibaba.excel.metadata.data.ReadCellData;
-import com.alibaba.excel.metadata.data.WriteCellData;
-import com.alibaba.excel.metadata.property.ExcelContentProperty;
-import com.ruoyi.common.core.utils.reflect.ReflectUtils;
-import com.ruoyi.common.excel.annotation.ExcelEnumFormat;
-import lombok.extern.slf4j.Slf4j;
-
-import java.lang.reflect.Field;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * 鏋氫妇鏍煎紡鍖栬浆鎹㈠鐞�
- *
- * @author Liang
- */
-@Slf4j
-public class ExcelEnumConvert implements Converter<Object> {
-
-    @Override
-    public Class<Object> supportJavaTypeKey() {
-        return Object.class;
-    }
-
-    @Override
-    public CellDataTypeEnum supportExcelTypeKey() {
-        return null;
-    }
-
-    @Override
-    public Object convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
-        Object codeValue = cellData.getData();
-        // 濡傛灉鏄┖鍊�
-        if (ObjectUtil.isNull(codeValue)) {
-            return null;
-        }
-        Map<Object, String> enumValueMap = beforeConvert(contentProperty);
-        String textValue = enumValueMap.get(codeValue);
-        return Convert.convert(contentProperty.getField().getType(), textValue);
-    }
-
-    @Override
-    public WriteCellData<String> convertToExcelData(Object object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
-        if (ObjectUtil.isNull(object)) {
-            return new WriteCellData<>("");
-        }
-        Map<Object, String> enumValueMap = beforeConvert(contentProperty);
-        String value = Convert.toStr(enumValueMap.get(object), "");
-        return new WriteCellData<>(value);
-    }
-
-    private Map<Object, String> beforeConvert(ExcelContentProperty contentProperty) {
-        ExcelEnumFormat anno = getAnnotation(contentProperty.getField());
-        Map<Object, String> enumValueMap = new HashMap<>();
-        Enum<?>[] enumConstants = anno.enumClass().getEnumConstants();
-        for (Enum<?> enumConstant : enumConstants) {
-            Object codeValue = ReflectUtils.invokeGetter(enumConstant, anno.codeField());
-            String textValue = ReflectUtils.invokeGetter(enumConstant, anno.textField());
-            enumValueMap.put(codeValue, textValue);
-        }
-        return enumValueMap;
-    }
-
-    private ExcelEnumFormat getAnnotation(Field field) {
-        return AnnotationUtil.getAnnotation(field, ExcelEnumFormat.class);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/core/CellMergeStrategy.java b/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/core/CellMergeStrategy.java
deleted file mode 100644
index b5bdd94..0000000
--- a/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/core/CellMergeStrategy.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package com.ruoyi.common.excel.core;
-
-import com.alibaba.excel.metadata.Head;
-import com.alibaba.excel.write.merge.AbstractMergeStrategy;
-import com.ruoyi.common.excel.annotation.CellMerge;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.SneakyThrows;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.poi.ss.usermodel.Cell;
-import org.apache.poi.ss.usermodel.Sheet;
-import org.apache.poi.ss.util.CellRangeAddress;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 鍒楀�奸噸澶嶅悎骞剁瓥鐣�
- *
- * @author Lion Li
- */
-@AllArgsConstructor
-@Slf4j
-public class CellMergeStrategy extends AbstractMergeStrategy {
-
-	private List<?> list;
-	private boolean hasTitle;
-
-	@Override
-	protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
-		List<CellRangeAddress> cellList = handle(list, hasTitle);
-		// judge the list is not null
-		if (CollectionUtils.isNotEmpty(cellList)) {
-			// the judge is necessary
-			if (cell.getRowIndex() == 1 && cell.getColumnIndex() == 0) {
-				for (CellRangeAddress item : cellList) {
-					sheet.addMergedRegion(item);
-				}
-			}
-		}
-	}
-
-	@SneakyThrows
-	private static List<CellRangeAddress> handle(List<?> list, boolean hasTitle) {
-		List<CellRangeAddress> cellList = new ArrayList<>();
-		if (CollectionUtils.isEmpty(list)) {
-			return cellList;
-		}
-		Class<?> clazz = list.get(0).getClass();
-		Field[] fields = clazz.getDeclaredFields();
-		// 鏈夋敞瑙g殑瀛楁
-		List<Field> mergeFields = new ArrayList<>();
-		List<Integer> mergeFieldsIndex = new ArrayList<>();
-		for (int i = 0; i < fields.length; i++) {
-			Field field = fields[i];
-			if (field.isAnnotationPresent(CellMerge.class)) {
-				CellMerge cm = field.getAnnotation(CellMerge.class);
-				mergeFields.add(field);
-				mergeFieldsIndex.add(cm.index() == -1 ? i : cm.index());
-			}
-		}
-		// 琛屽悎骞跺紑濮嬩笅鏍�
-		int rowIndex = hasTitle ? 1 : 0;
-		Map<Field, RepeatCell> map = new HashMap<>();
-		// 鐢熸垚涓や袱鍚堝苟鍗曞厓鏍�
-		for (int i = 0; i < list.size(); i++) {
-			for (int j = 0; j < mergeFields.size(); j++) {
-				Field field = mergeFields.get(j);
-				String name = field.getName();
-				String methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
-				Method readMethod = clazz.getMethod(methodName);
-				Object val = readMethod.invoke(list.get(i));
-
-				int colNum = mergeFieldsIndex.get(j);
-				if (!map.containsKey(field)) {
-					map.put(field, new RepeatCell(val, i));
-				} else {
-					RepeatCell repeatCell = map.get(field);
-					Object cellValue = repeatCell.getValue();
-					if (cellValue == null || "".equals(cellValue)) {
-						// 绌哄�艰烦杩囦笉鍚堝苟
-						continue;
-					}
-					if (!cellValue.equals(val)) {
-						if (i - repeatCell.getCurrent() > 1) {
-							cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex - 1, colNum, colNum));
-						}
-						map.put(field, new RepeatCell(val, i));
-					} else if (i == list.size() - 1) {
-						if (i > repeatCell.getCurrent()) {
-							cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum));
-						}
-					}
-				}
-			}
-		}
-		return cellList;
-	}
-
-	@Data
-	@AllArgsConstructor
-	static class RepeatCell {
-
-		private Object value;
-
-		private int current;
-
-	}
-}
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/core/DefaultExcelListener.java b/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/core/DefaultExcelListener.java
deleted file mode 100644
index d493218..0000000
--- a/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/core/DefaultExcelListener.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package com.ruoyi.common.excel.core;
-
-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.ruoyi.common.core.utils.StreamUtils;
-import com.ruoyi.common.core.utils.ValidatorUtils;
-import com.ruoyi.common.json.utils.JsonUtils;
-import jakarta.validation.ConstraintViolation;
-import jakarta.validation.ConstraintViolationException;
-import lombok.NoArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-
-import java.util.Map;
-import java.util.Set;
-
-/**
- * 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) {
-            // 濡傛灉鏄煇涓�涓崟鍏冩牸鐨勮浆鎹㈠紓甯� 鑳借幏鍙栧埌鍏蜂綋琛屽彿
-            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) {
-            Set<ConstraintViolation<?>> constraintViolations = constraintViolationException.getConstraintViolations();
-            String constraintViolationsMsg = StreamUtils.join(constraintViolations, ConstraintViolation::getMessage, ", ");
-            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瀽鍒颁竴鏉¤〃澶存暟鎹�: {}", JsonUtils.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/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/core/DefautExcelResult.java b/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/core/DefautExcelResult.java
deleted file mode 100644
index af678ef..0000000
--- a/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/core/DefautExcelResult.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.ruoyi.common.excel.core;
-
-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/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/core/ExcelListener.java b/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/core/ExcelListener.java
deleted file mode 100644
index 093b94f..0000000
--- a/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/core/ExcelListener.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.ruoyi.common.excel.core;
-
-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/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/core/ExcelResult.java b/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/core/ExcelResult.java
deleted file mode 100644
index 81aab5d..0000000
--- a/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/core/ExcelResult.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.ruoyi.common.excel.core;
-
-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/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/utils/ExcelUtil.java b/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/utils/ExcelUtil.java
deleted file mode 100644
index 2e77701..0000000
--- a/ruoyi-common/ruoyi-common-excel/src/main/java/com/ruoyi/common/excel/utils/ExcelUtil.java
+++ /dev/null
@@ -1,327 +0,0 @@
-package com.ruoyi.common.excel.utils;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.io.resource.ClassPathResource;
-import cn.hutool.core.util.IdUtil;
-import com.alibaba.excel.EasyExcel;
-import com.alibaba.excel.ExcelWriter;
-import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
-import com.alibaba.excel.write.metadata.WriteSheet;
-import com.alibaba.excel.write.metadata.fill.FillConfig;
-import com.alibaba.excel.write.metadata.fill.FillWrapper;
-import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.core.utils.file.FileUtils;
-import com.ruoyi.common.excel.convert.ExcelBigNumberConvert;
-import com.ruoyi.common.excel.core.CellMergeStrategy;
-import com.ruoyi.common.excel.core.DefaultExcelListener;
-import com.ruoyi.common.excel.core.ExcelListener;
-import com.ruoyi.common.excel.core.ExcelResult;
-import jakarta.servlet.ServletOutputStream;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Excel鐩稿叧澶勭悊
- *
- * @author Lion Li
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class ExcelUtil {
-
-    /**
-     * 鍚屾瀵煎叆(閫傜敤浜庡皬鏁版嵁閲�)
-     *
-     * @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         杈撳叆娴�
-     * @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();
-    }
-
-    /**
-     * 浣跨敤鑷畾涔夌洃鍚櫒 寮傛瀵煎叆 鑷畾涔夎繑鍥�
-     *
-     * @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();
-    }
-
-    /**
-     * 瀵煎嚭excel
-     *
-     * @param list      瀵煎嚭鏁版嵁闆嗗悎
-     * @param sheetName 宸ヤ綔琛ㄧ殑鍚嶇О
-     * @param clazz     瀹炰綋绫�
-     * @param response  鍝嶅簲浣�
-     */
-    public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, HttpServletResponse response) {
-        try {
-            resetResponse(sheetName, response);
-            ServletOutputStream os = response.getOutputStream();
-            exportExcel(list, sheetName, clazz, false, os);
-        } catch (IOException e) {
-            throw new RuntimeException("瀵煎嚭Excel寮傚父");
-        }
-    }
-
-    /**
-     * 瀵煎嚭excel
-     *
-     * @param list      瀵煎嚭鏁版嵁闆嗗悎
-     * @param sheetName 宸ヤ綔琛ㄧ殑鍚嶇О
-     * @param clazz     瀹炰綋绫�
-     * @param merge     鏄惁鍚堝苟鍗曞厓鏍�
-     * @param response  鍝嶅簲浣�
-     */
-    public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, boolean merge, HttpServletResponse response) {
-        try {
-            resetResponse(sheetName, response);
-            ServletOutputStream os = response.getOutputStream();
-            exportExcel(list, sheetName, clazz, merge, os);
-        } catch (IOException e) {
-            throw new RuntimeException("瀵煎嚭Excel寮傚父");
-        }
-    }
-
-    /**
-     * 瀵煎嚭excel
-     *
-     * @param list      瀵煎嚭鏁版嵁闆嗗悎
-     * @param sheetName 宸ヤ綔琛ㄧ殑鍚嶇О
-     * @param clazz     瀹炰綋绫�
-     * @param os        杈撳嚭娴�
-     */
-    public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, OutputStream os) {
-        exportExcel(list, sheetName, clazz, false, os);
-    }
-
-    /**
-     * 瀵煎嚭excel
-     *
-     * @param list      瀵煎嚭鏁版嵁闆嗗悎
-     * @param sheetName 宸ヤ綔琛ㄧ殑鍚嶇О
-     * @param clazz     瀹炰綋绫�
-     * @param merge     鏄惁鍚堝苟鍗曞厓鏍�
-     * @param os        杈撳嚭娴�
-     */
-    public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, boolean merge, OutputStream os) {
-        ExcelWriterSheetBuilder builder = EasyExcel.write(os, clazz)
-            .autoCloseStream(false)
-            // 鑷姩閫傞厤
-            .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
-            // 澶ф暟鍊艰嚜鍔ㄨ浆鎹� 闃叉澶辩湡
-            .registerConverter(new ExcelBigNumberConvert())
-            .sheet(sheetName);
-        if (merge) {
-            // 鍚堝苟澶勭悊鍣�
-            builder.registerWriteHandler(new CellMergeStrategy(list, true));
-        }
-        builder.doWrite(list);
-    }
-
-    /**
-     * 鍗曡〃澶氭暟鎹ā鏉垮鍑� 妯℃澘鏍煎紡涓� {.灞炴�
-     *
-     * @param filename     鏂囦欢鍚�
-     * @param templatePath 妯℃澘璺緞 resource 鐩綍涓嬬殑璺緞鍖呮嫭妯℃澘鏂囦欢鍚�
-     *                     渚嬪: excel/temp.xlsx
-     *                     閲嶇偣: 妯℃澘鏂囦欢蹇呴』鏀剧疆鍒板惎鍔ㄧ被瀵瑰簲鐨� resource 鐩綍涓�
-     * @param data         妯℃澘闇�瑕佺殑鏁版嵁
-     * @param response     鍝嶅簲浣�
-     */
-    public static void exportTemplate(List<Object> data, String filename, String templatePath, HttpServletResponse response) {
-        try {
-            resetResponse(filename, response);
-            ServletOutputStream os = response.getOutputStream();
-            exportTemplate(data, templatePath, os);
-        } catch (IOException e) {
-            throw new RuntimeException("瀵煎嚭Excel寮傚父");
-        }
-    }
-
-    /**
-     * 鍗曡〃澶氭暟鎹ā鏉垮鍑� 妯℃澘鏍煎紡涓� {.灞炴�
-     *
-     * @param templatePath 妯℃澘璺緞 resource 鐩綍涓嬬殑璺緞鍖呮嫭妯℃澘鏂囦欢鍚�
-     *                     渚嬪: excel/temp.xlsx
-     *                     閲嶇偣: 妯℃澘鏂囦欢蹇呴』鏀剧疆鍒板惎鍔ㄧ被瀵瑰簲鐨� resource 鐩綍涓�
-     * @param data         妯℃澘闇�瑕佺殑鏁版嵁
-     * @param os           杈撳嚭娴�
-     */
-    public static void exportTemplate(List<Object> data, String templatePath, OutputStream os) {
-        ClassPathResource templateResource = new ClassPathResource(templatePath);
-        ExcelWriter excelWriter = EasyExcel.write(os)
-            .withTemplate(templateResource.getStream())
-            .autoCloseStream(false)
-            // 澶ф暟鍊艰嚜鍔ㄨ浆鎹� 闃叉澶辩湡
-            .registerConverter(new ExcelBigNumberConvert())
-            .build();
-        WriteSheet writeSheet = EasyExcel.writerSheet().build();
-        if (CollUtil.isEmpty(data)) {
-            throw new IllegalArgumentException("鏁版嵁涓虹┖");
-        }
-        // 鍗曡〃澶氭暟鎹鍑� 妯℃澘鏍煎紡涓� {.灞炴�
-        for (Object d : data) {
-            excelWriter.fill(d, writeSheet);
-        }
-        excelWriter.finish();
-    }
-
-    /**
-     * 澶氳〃澶氭暟鎹ā鏉垮鍑� 妯℃澘鏍煎紡涓� {key.灞炴�
-     *
-     * @param filename     鏂囦欢鍚�
-     * @param templatePath 妯℃澘璺緞 resource 鐩綍涓嬬殑璺緞鍖呮嫭妯℃澘鏂囦欢鍚�
-     *                     渚嬪: excel/temp.xlsx
-     *                     閲嶇偣: 妯℃澘鏂囦欢蹇呴』鏀剧疆鍒板惎鍔ㄧ被瀵瑰簲鐨� resource 鐩綍涓�
-     * @param data         妯℃澘闇�瑕佺殑鏁版嵁
-     * @param response     鍝嶅簲浣�
-     */
-    public static void exportTemplateMultiList(Map<String, Object> data, String filename, String templatePath, HttpServletResponse response) {
-        try {
-            resetResponse(filename, response);
-            ServletOutputStream os = response.getOutputStream();
-            exportTemplateMultiList(data, templatePath, os);
-        } catch (IOException e) {
-            throw new RuntimeException("瀵煎嚭Excel寮傚父");
-        }
-    }
-
-    /**
-     * 澶氳〃澶氭暟鎹ā鏉垮鍑� 妯℃澘鏍煎紡涓� {key.灞炴�
-     *
-     * @param templatePath 妯℃澘璺緞 resource 鐩綍涓嬬殑璺緞鍖呮嫭妯℃澘鏂囦欢鍚�
-     *                     渚嬪: excel/temp.xlsx
-     *                     閲嶇偣: 妯℃澘鏂囦欢蹇呴』鏀剧疆鍒板惎鍔ㄧ被瀵瑰簲鐨� resource 鐩綍涓�
-     * @param data         妯℃澘闇�瑕佺殑鏁版嵁
-     * @param os           杈撳嚭娴�
-     */
-    public static void exportTemplateMultiList(Map<String, Object> data, String templatePath, OutputStream os) {
-        ClassPathResource templateResource = new ClassPathResource(templatePath);
-        ExcelWriter excelWriter = EasyExcel.write(os)
-            .withTemplate(templateResource.getStream())
-            .autoCloseStream(false)
-            // 澶ф暟鍊艰嚜鍔ㄨ浆鎹� 闃叉澶辩湡
-            .registerConverter(new ExcelBigNumberConvert())
-            .build();
-        WriteSheet writeSheet = EasyExcel.writerSheet().build();
-        if (CollUtil.isEmpty(data)) {
-            throw new IllegalArgumentException("鏁版嵁涓虹┖");
-        }
-        for (Map.Entry<String, Object> map : data.entrySet()) {
-            // 璁剧疆鍒楄〃鍚庣画杩樻湁鏁版嵁
-            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
-            if (map.getValue() instanceof Collection) {
-                // 澶氳〃瀵煎嚭蹇呴』浣跨敤 FillWrapper
-                excelWriter.fill(new FillWrapper(map.getKey(), (Collection<?>) map.getValue()), fillConfig, writeSheet);
-            } else {
-                excelWriter.fill(map.getValue(), writeSheet);
-            }
-        }
-        excelWriter.finish();
-    }
-
-    /**
-     * 閲嶇疆鍝嶅簲浣�
-     */
-    private static void resetResponse(String sheetName, HttpServletResponse response) {
-        String filename = encodingFilename(sheetName);
-        FileUtils.setAttachmentResponseHeader(response, filename);
-        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
-    }
-
-    /**
-     * 瑙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(StringUtils.SEPARATOR);
-        for (String item : convertSource) {
-            String[] itemArray = item.split("=");
-            if (StringUtils.containsAny(propertyValue, separator)) {
-                for (String value : propertyValue.split(separator)) {
-                    if (itemArray[0].equals(value)) {
-                        propertyString.append(itemArray[1]).append(separator);
-                        break;
-                    }
-                }
-            } else {
-                if (itemArray[0].equals(propertyValue)) {
-                    return itemArray[1];
-                }
-            }
-        }
-        return StringUtils.stripEnd(propertyString.toString(), separator);
-    }
-
-    /**
-     * 鍙嶅悜瑙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(StringUtils.SEPARATOR);
-        for (String item : convertSource) {
-            String[] itemArray = item.split("=");
-            if (StringUtils.containsAny(propertyValue, separator)) {
-                for (String value : propertyValue.split(separator)) {
-                    if (itemArray[1].equals(value)) {
-                        propertyString.append(itemArray[0]).append(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-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/annotation/CellMerge.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/annotation/CellMerge.java
new file mode 100644
index 0000000..bbdaaa1
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/annotation/CellMerge.java
@@ -0,0 +1,24 @@
+package org.dromara.common.excel.annotation;
+
+import org.dromara.common.excel.core.CellMergeStrategy;
+
+import java.lang.annotation.*;
+
+/**
+ * excel 鍒楀崟鍏冩牸鍚堝苟(鍚堝苟鍒楃浉鍚岄」)
+ *
+ * 闇�鎼厤 {@link CellMergeStrategy} 绛栫暐浣跨敤
+ *
+ * @author Lion Li
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface CellMerge {
+
+	/**
+	 * col index
+	 */
+	int index() default -1;
+
+}
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/annotation/ExcelDictFormat.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/annotation/ExcelDictFormat.java
new file mode 100644
index 0000000..5c51842
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/annotation/ExcelDictFormat.java
@@ -0,0 +1,32 @@
+package org.dromara.common.excel.annotation;
+
+import org.dromara.common.core.utils.StringUtils;
+
+import java.lang.annotation.*;
+
+/**
+ * 瀛楀吀鏍煎紡鍖�
+ *
+ * @author Lion Li
+ */
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface ExcelDictFormat {
+
+    /**
+     * 濡傛灉鏄瓧鍏哥被鍨嬶紝璇疯缃瓧鍏哥殑type鍊� (濡�: sys_user_sex)
+     */
+    String dictType() default "";
+
+    /**
+     * 璇诲彇鍐呭杞〃杈惧紡 (濡�: 0=鐢�,1=濂�,2=鏈煡)
+     */
+    String readConverterExp() default "";
+
+    /**
+     * 鍒嗛殧绗︼紝璇诲彇瀛楃涓茬粍鍐呭
+     */
+    String separator() default StringUtils.SEPARATOR;
+
+}
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/annotation/ExcelEnumFormat.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/annotation/ExcelEnumFormat.java
new file mode 100644
index 0000000..290379d
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/annotation/ExcelEnumFormat.java
@@ -0,0 +1,30 @@
+package org.dromara.common.excel.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 鏋氫妇鏍煎紡鍖�
+ *
+ * @author Liang
+ */
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface ExcelEnumFormat {
+
+    /**
+     * 瀛楀吀鏋氫妇绫诲瀷
+     */
+    Class<? extends Enum<?>> enumClass();
+
+    /**
+     * 瀛楀吀鏋氫妇绫讳腑瀵瑰簲鐨刢ode灞炴�у悕绉帮紝榛樿涓篶ode
+     */
+    String codeField() default "code";
+
+    /**
+     * 瀛楀吀鏋氫妇绫讳腑瀵瑰簲鐨則ext灞炴�у悕绉帮紝榛樿涓簍ext
+     */
+    String textField() default "text";
+
+}
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelBigNumberConvert.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelBigNumberConvert.java
new file mode 100644
index 0000000..07cc4c4
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelBigNumberConvert.java
@@ -0,0 +1,52 @@
+package org.dromara.common.excel.convert;
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.data.ReadCellData;
+import com.alibaba.excel.metadata.data.WriteCellData;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+import lombok.extern.slf4j.Slf4j;
+
+import java.math.BigDecimal;
+
+/**
+ * 澶ф暟鍊艰浆鎹�
+ * Excel 鏁板�奸暱搴︿綅15浣� 澶т簬15浣嶇殑鏁板�艰浆鎹綅瀛楃涓�
+ *
+ * @author Lion Li
+ */
+@Slf4j
+public class ExcelBigNumberConvert implements Converter<Long> {
+
+    @Override
+    public Class<Long> supportJavaTypeKey() {
+        return Long.class;
+    }
+
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        return CellDataTypeEnum.STRING;
+    }
+
+    @Override
+    public Long convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
+        return Convert.toLong(cellData.getData());
+    }
+
+    @Override
+    public WriteCellData<Object> convertToExcelData(Long object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
+        if (ObjectUtil.isNotNull(object)) {
+            String str = Convert.toStr(object);
+            if (str.length() > 15) {
+                return new WriteCellData<>(str);
+            }
+        }
+        WriteCellData<Object> cellData = new WriteCellData<>(new BigDecimal(object));
+        cellData.setType(CellDataTypeEnum.NUMBER);
+        return cellData;
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelDictConvert.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelDictConvert.java
new file mode 100644
index 0000000..61eeabf
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelDictConvert.java
@@ -0,0 +1,73 @@
+package org.dromara.common.excel.convert;
+
+import cn.hutool.core.annotation.AnnotationUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.data.ReadCellData;
+import com.alibaba.excel.metadata.data.WriteCellData;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.core.service.DictService;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.excel.utils.ExcelUtil;
+import lombok.extern.slf4j.Slf4j;
+
+import java.lang.reflect.Field;
+
+/**
+ * 瀛楀吀鏍煎紡鍖栬浆鎹㈠鐞�
+ *
+ * @author Lion Li
+ */
+@Slf4j
+public class ExcelDictConvert implements Converter<Object> {
+
+    @Override
+    public Class<Object> supportJavaTypeKey() {
+        return Object.class;
+    }
+
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        return null;
+    }
+
+    @Override
+    public Object convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
+        ExcelDictFormat anno = getAnnotation(contentProperty.getField());
+        String type = anno.dictType();
+        String label = cellData.getStringValue();
+        String value;
+        if (StringUtils.isBlank(type)) {
+            value = ExcelUtil.reverseByExp(label, anno.readConverterExp(), anno.separator());
+        } else {
+            value = SpringUtils.getBean(DictService.class).getDictValue(type, label, anno.separator());
+        }
+        return Convert.convert(contentProperty.getField().getType(), value);
+    }
+
+    @Override
+    public WriteCellData<String> convertToExcelData(Object object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
+        if (ObjectUtil.isNull(object)) {
+            return new WriteCellData<>("");
+        }
+        ExcelDictFormat anno = getAnnotation(contentProperty.getField());
+        String type = anno.dictType();
+        String value = Convert.toStr(object);
+        String label;
+        if (StringUtils.isBlank(type)) {
+            label = ExcelUtil.convertByExp(value, anno.readConverterExp(), anno.separator());
+        } else {
+            label = SpringUtils.getBean(DictService.class).getDictLabel(type, value, anno.separator());
+        }
+        return new WriteCellData<>(label);
+    }
+
+    private ExcelDictFormat getAnnotation(Field field) {
+        return AnnotationUtil.getAnnotation(field, ExcelDictFormat.class);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelEnumConvert.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelEnumConvert.java
new file mode 100644
index 0000000..3b52695
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelEnumConvert.java
@@ -0,0 +1,75 @@
+package org.dromara.common.excel.convert;
+
+import cn.hutool.core.annotation.AnnotationUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.data.ReadCellData;
+import com.alibaba.excel.metadata.data.WriteCellData;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+import org.dromara.common.core.utils.reflect.ReflectUtils;
+import org.dromara.common.excel.annotation.ExcelEnumFormat;
+import lombok.extern.slf4j.Slf4j;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 鏋氫妇鏍煎紡鍖栬浆鎹㈠鐞�
+ *
+ * @author Liang
+ */
+@Slf4j
+public class ExcelEnumConvert implements Converter<Object> {
+
+    @Override
+    public Class<Object> supportJavaTypeKey() {
+        return Object.class;
+    }
+
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        return null;
+    }
+
+    @Override
+    public Object convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
+        Object codeValue = cellData.getData();
+        // 濡傛灉鏄┖鍊�
+        if (ObjectUtil.isNull(codeValue)) {
+            return null;
+        }
+        Map<Object, String> enumValueMap = beforeConvert(contentProperty);
+        String textValue = enumValueMap.get(codeValue);
+        return Convert.convert(contentProperty.getField().getType(), textValue);
+    }
+
+    @Override
+    public WriteCellData<String> convertToExcelData(Object object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
+        if (ObjectUtil.isNull(object)) {
+            return new WriteCellData<>("");
+        }
+        Map<Object, String> enumValueMap = beforeConvert(contentProperty);
+        String value = Convert.toStr(enumValueMap.get(object), "");
+        return new WriteCellData<>(value);
+    }
+
+    private Map<Object, String> beforeConvert(ExcelContentProperty contentProperty) {
+        ExcelEnumFormat anno = getAnnotation(contentProperty.getField());
+        Map<Object, String> enumValueMap = new HashMap<>();
+        Enum<?>[] enumConstants = anno.enumClass().getEnumConstants();
+        for (Enum<?> enumConstant : enumConstants) {
+            Object codeValue = ReflectUtils.invokeGetter(enumConstant, anno.codeField());
+            String textValue = ReflectUtils.invokeGetter(enumConstant, anno.textField());
+            enumValueMap.put(codeValue, textValue);
+        }
+        return enumValueMap;
+    }
+
+    private ExcelEnumFormat getAnnotation(Field field) {
+        return AnnotationUtil.getAnnotation(field, ExcelEnumFormat.class);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/CellMergeStrategy.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/CellMergeStrategy.java
new file mode 100644
index 0000000..a409372
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/CellMergeStrategy.java
@@ -0,0 +1,114 @@
+package org.dromara.common.excel.core;
+
+import com.alibaba.excel.metadata.Head;
+import com.alibaba.excel.write.merge.AbstractMergeStrategy;
+import org.dromara.common.excel.annotation.CellMerge;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.util.CellRangeAddress;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 鍒楀�奸噸澶嶅悎骞剁瓥鐣�
+ *
+ * @author Lion Li
+ */
+@AllArgsConstructor
+@Slf4j
+public class CellMergeStrategy extends AbstractMergeStrategy {
+
+	private List<?> list;
+	private boolean hasTitle;
+
+	@Override
+	protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
+		List<CellRangeAddress> cellList = handle(list, hasTitle);
+		// judge the list is not null
+		if (CollectionUtils.isNotEmpty(cellList)) {
+			// the judge is necessary
+			if (cell.getRowIndex() == 1 && cell.getColumnIndex() == 0) {
+				for (CellRangeAddress item : cellList) {
+					sheet.addMergedRegion(item);
+				}
+			}
+		}
+	}
+
+	@SneakyThrows
+	private static List<CellRangeAddress> handle(List<?> list, boolean hasTitle) {
+		List<CellRangeAddress> cellList = new ArrayList<>();
+		if (CollectionUtils.isEmpty(list)) {
+			return cellList;
+		}
+		Class<?> clazz = list.get(0).getClass();
+		Field[] fields = clazz.getDeclaredFields();
+		// 鏈夋敞瑙g殑瀛楁
+		List<Field> mergeFields = new ArrayList<>();
+		List<Integer> mergeFieldsIndex = new ArrayList<>();
+		for (int i = 0; i < fields.length; i++) {
+			Field field = fields[i];
+			if (field.isAnnotationPresent(CellMerge.class)) {
+				CellMerge cm = field.getAnnotation(CellMerge.class);
+				mergeFields.add(field);
+				mergeFieldsIndex.add(cm.index() == -1 ? i : cm.index());
+			}
+		}
+		// 琛屽悎骞跺紑濮嬩笅鏍�
+		int rowIndex = hasTitle ? 1 : 0;
+		Map<Field, RepeatCell> map = new HashMap<>();
+		// 鐢熸垚涓や袱鍚堝苟鍗曞厓鏍�
+		for (int i = 0; i < list.size(); i++) {
+			for (int j = 0; j < mergeFields.size(); j++) {
+				Field field = mergeFields.get(j);
+				String name = field.getName();
+				String methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
+				Method readMethod = clazz.getMethod(methodName);
+				Object val = readMethod.invoke(list.get(i));
+
+				int colNum = mergeFieldsIndex.get(j);
+				if (!map.containsKey(field)) {
+					map.put(field, new RepeatCell(val, i));
+				} else {
+					RepeatCell repeatCell = map.get(field);
+					Object cellValue = repeatCell.getValue();
+					if (cellValue == null || "".equals(cellValue)) {
+						// 绌哄�艰烦杩囦笉鍚堝苟
+						continue;
+					}
+					if (!cellValue.equals(val)) {
+						if (i - repeatCell.getCurrent() > 1) {
+							cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex - 1, colNum, colNum));
+						}
+						map.put(field, new RepeatCell(val, i));
+					} else if (i == list.size() - 1) {
+						if (i > repeatCell.getCurrent()) {
+							cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum));
+						}
+					}
+				}
+			}
+		}
+		return cellList;
+	}
+
+	@Data
+	@AllArgsConstructor
+	static class RepeatCell {
+
+		private Object value;
+
+		private int current;
+
+	}
+}
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/DefaultExcelListener.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/DefaultExcelListener.java
new file mode 100644
index 0000000..c5d00a3
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/DefaultExcelListener.java
@@ -0,0 +1,104 @@
+package org.dromara.common.excel.core;
+
+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 org.dromara.common.core.utils.StreamUtils;
+import org.dromara.common.core.utils.ValidatorUtils;
+import org.dromara.common.json.utils.JsonUtils;
+import jakarta.validation.ConstraintViolation;
+import jakarta.validation.ConstraintViolationException;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 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) {
+            // 濡傛灉鏄煇涓�涓崟鍏冩牸鐨勮浆鎹㈠紓甯� 鑳借幏鍙栧埌鍏蜂綋琛屽彿
+            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) {
+            Set<ConstraintViolation<?>> constraintViolations = constraintViolationException.getConstraintViolations();
+            String constraintViolationsMsg = StreamUtils.join(constraintViolations, ConstraintViolation::getMessage, ", ");
+            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瀽鍒颁竴鏉¤〃澶存暟鎹�: {}", JsonUtils.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/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/DefautExcelResult.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/DefautExcelResult.java
new file mode 100644
index 0000000..d61e292
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/DefautExcelResult.java
@@ -0,0 +1,73 @@
+package org.dromara.common.excel.core;
+
+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/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/ExcelListener.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/ExcelListener.java
new file mode 100644
index 0000000..2d0340f
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/ExcelListener.java
@@ -0,0 +1,14 @@
+package org.dromara.common.excel.core;
+
+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/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/ExcelResult.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/ExcelResult.java
new file mode 100644
index 0000000..0c2a418
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/ExcelResult.java
@@ -0,0 +1,26 @@
+package org.dromara.common.excel.core;
+
+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/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java
new file mode 100644
index 0000000..3605cf2
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java
@@ -0,0 +1,327 @@
+package org.dromara.common.excel.utils;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.io.resource.ClassPathResource;
+import cn.hutool.core.util.IdUtil;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.ExcelWriter;
+import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
+import com.alibaba.excel.write.metadata.WriteSheet;
+import com.alibaba.excel.write.metadata.fill.FillConfig;
+import com.alibaba.excel.write.metadata.fill.FillWrapper;
+import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.core.utils.file.FileUtils;
+import org.dromara.common.excel.convert.ExcelBigNumberConvert;
+import org.dromara.common.excel.core.CellMergeStrategy;
+import org.dromara.common.excel.core.DefaultExcelListener;
+import org.dromara.common.excel.core.ExcelListener;
+import org.dromara.common.excel.core.ExcelResult;
+import jakarta.servlet.ServletOutputStream;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Excel鐩稿叧澶勭悊
+ *
+ * @author Lion Li
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class ExcelUtil {
+
+    /**
+     * 鍚屾瀵煎叆(閫傜敤浜庡皬鏁版嵁閲�)
+     *
+     * @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         杈撳叆娴�
+     * @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();
+    }
+
+    /**
+     * 浣跨敤鑷畾涔夌洃鍚櫒 寮傛瀵煎叆 鑷畾涔夎繑鍥�
+     *
+     * @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();
+    }
+
+    /**
+     * 瀵煎嚭excel
+     *
+     * @param list      瀵煎嚭鏁版嵁闆嗗悎
+     * @param sheetName 宸ヤ綔琛ㄧ殑鍚嶇О
+     * @param clazz     瀹炰綋绫�
+     * @param response  鍝嶅簲浣�
+     */
+    public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, HttpServletResponse response) {
+        try {
+            resetResponse(sheetName, response);
+            ServletOutputStream os = response.getOutputStream();
+            exportExcel(list, sheetName, clazz, false, os);
+        } catch (IOException e) {
+            throw new RuntimeException("瀵煎嚭Excel寮傚父");
+        }
+    }
+
+    /**
+     * 瀵煎嚭excel
+     *
+     * @param list      瀵煎嚭鏁版嵁闆嗗悎
+     * @param sheetName 宸ヤ綔琛ㄧ殑鍚嶇О
+     * @param clazz     瀹炰綋绫�
+     * @param merge     鏄惁鍚堝苟鍗曞厓鏍�
+     * @param response  鍝嶅簲浣�
+     */
+    public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, boolean merge, HttpServletResponse response) {
+        try {
+            resetResponse(sheetName, response);
+            ServletOutputStream os = response.getOutputStream();
+            exportExcel(list, sheetName, clazz, merge, os);
+        } catch (IOException e) {
+            throw new RuntimeException("瀵煎嚭Excel寮傚父");
+        }
+    }
+
+    /**
+     * 瀵煎嚭excel
+     *
+     * @param list      瀵煎嚭鏁版嵁闆嗗悎
+     * @param sheetName 宸ヤ綔琛ㄧ殑鍚嶇О
+     * @param clazz     瀹炰綋绫�
+     * @param os        杈撳嚭娴�
+     */
+    public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, OutputStream os) {
+        exportExcel(list, sheetName, clazz, false, os);
+    }
+
+    /**
+     * 瀵煎嚭excel
+     *
+     * @param list      瀵煎嚭鏁版嵁闆嗗悎
+     * @param sheetName 宸ヤ綔琛ㄧ殑鍚嶇О
+     * @param clazz     瀹炰綋绫�
+     * @param merge     鏄惁鍚堝苟鍗曞厓鏍�
+     * @param os        杈撳嚭娴�
+     */
+    public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, boolean merge, OutputStream os) {
+        ExcelWriterSheetBuilder builder = EasyExcel.write(os, clazz)
+            .autoCloseStream(false)
+            // 鑷姩閫傞厤
+            .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
+            // 澶ф暟鍊艰嚜鍔ㄨ浆鎹� 闃叉澶辩湡
+            .registerConverter(new ExcelBigNumberConvert())
+            .sheet(sheetName);
+        if (merge) {
+            // 鍚堝苟澶勭悊鍣�
+            builder.registerWriteHandler(new CellMergeStrategy(list, true));
+        }
+        builder.doWrite(list);
+    }
+
+    /**
+     * 鍗曡〃澶氭暟鎹ā鏉垮鍑� 妯℃澘鏍煎紡涓� {.灞炴�
+     *
+     * @param filename     鏂囦欢鍚�
+     * @param templatePath 妯℃澘璺緞 resource 鐩綍涓嬬殑璺緞鍖呮嫭妯℃澘鏂囦欢鍚�
+     *                     渚嬪: excel/temp.xlsx
+     *                     閲嶇偣: 妯℃澘鏂囦欢蹇呴』鏀剧疆鍒板惎鍔ㄧ被瀵瑰簲鐨� resource 鐩綍涓�
+     * @param data         妯℃澘闇�瑕佺殑鏁版嵁
+     * @param response     鍝嶅簲浣�
+     */
+    public static void exportTemplate(List<Object> data, String filename, String templatePath, HttpServletResponse response) {
+        try {
+            resetResponse(filename, response);
+            ServletOutputStream os = response.getOutputStream();
+            exportTemplate(data, templatePath, os);
+        } catch (IOException e) {
+            throw new RuntimeException("瀵煎嚭Excel寮傚父");
+        }
+    }
+
+    /**
+     * 鍗曡〃澶氭暟鎹ā鏉垮鍑� 妯℃澘鏍煎紡涓� {.灞炴�
+     *
+     * @param templatePath 妯℃澘璺緞 resource 鐩綍涓嬬殑璺緞鍖呮嫭妯℃澘鏂囦欢鍚�
+     *                     渚嬪: excel/temp.xlsx
+     *                     閲嶇偣: 妯℃澘鏂囦欢蹇呴』鏀剧疆鍒板惎鍔ㄧ被瀵瑰簲鐨� resource 鐩綍涓�
+     * @param data         妯℃澘闇�瑕佺殑鏁版嵁
+     * @param os           杈撳嚭娴�
+     */
+    public static void exportTemplate(List<Object> data, String templatePath, OutputStream os) {
+        ClassPathResource templateResource = new ClassPathResource(templatePath);
+        ExcelWriter excelWriter = EasyExcel.write(os)
+            .withTemplate(templateResource.getStream())
+            .autoCloseStream(false)
+            // 澶ф暟鍊艰嚜鍔ㄨ浆鎹� 闃叉澶辩湡
+            .registerConverter(new ExcelBigNumberConvert())
+            .build();
+        WriteSheet writeSheet = EasyExcel.writerSheet().build();
+        if (CollUtil.isEmpty(data)) {
+            throw new IllegalArgumentException("鏁版嵁涓虹┖");
+        }
+        // 鍗曡〃澶氭暟鎹鍑� 妯℃澘鏍煎紡涓� {.灞炴�
+        for (Object d : data) {
+            excelWriter.fill(d, writeSheet);
+        }
+        excelWriter.finish();
+    }
+
+    /**
+     * 澶氳〃澶氭暟鎹ā鏉垮鍑� 妯℃澘鏍煎紡涓� {key.灞炴�
+     *
+     * @param filename     鏂囦欢鍚�
+     * @param templatePath 妯℃澘璺緞 resource 鐩綍涓嬬殑璺緞鍖呮嫭妯℃澘鏂囦欢鍚�
+     *                     渚嬪: excel/temp.xlsx
+     *                     閲嶇偣: 妯℃澘鏂囦欢蹇呴』鏀剧疆鍒板惎鍔ㄧ被瀵瑰簲鐨� resource 鐩綍涓�
+     * @param data         妯℃澘闇�瑕佺殑鏁版嵁
+     * @param response     鍝嶅簲浣�
+     */
+    public static void exportTemplateMultiList(Map<String, Object> data, String filename, String templatePath, HttpServletResponse response) {
+        try {
+            resetResponse(filename, response);
+            ServletOutputStream os = response.getOutputStream();
+            exportTemplateMultiList(data, templatePath, os);
+        } catch (IOException e) {
+            throw new RuntimeException("瀵煎嚭Excel寮傚父");
+        }
+    }
+
+    /**
+     * 澶氳〃澶氭暟鎹ā鏉垮鍑� 妯℃澘鏍煎紡涓� {key.灞炴�
+     *
+     * @param templatePath 妯℃澘璺緞 resource 鐩綍涓嬬殑璺緞鍖呮嫭妯℃澘鏂囦欢鍚�
+     *                     渚嬪: excel/temp.xlsx
+     *                     閲嶇偣: 妯℃澘鏂囦欢蹇呴』鏀剧疆鍒板惎鍔ㄧ被瀵瑰簲鐨� resource 鐩綍涓�
+     * @param data         妯℃澘闇�瑕佺殑鏁版嵁
+     * @param os           杈撳嚭娴�
+     */
+    public static void exportTemplateMultiList(Map<String, Object> data, String templatePath, OutputStream os) {
+        ClassPathResource templateResource = new ClassPathResource(templatePath);
+        ExcelWriter excelWriter = EasyExcel.write(os)
+            .withTemplate(templateResource.getStream())
+            .autoCloseStream(false)
+            // 澶ф暟鍊艰嚜鍔ㄨ浆鎹� 闃叉澶辩湡
+            .registerConverter(new ExcelBigNumberConvert())
+            .build();
+        WriteSheet writeSheet = EasyExcel.writerSheet().build();
+        if (CollUtil.isEmpty(data)) {
+            throw new IllegalArgumentException("鏁版嵁涓虹┖");
+        }
+        for (Map.Entry<String, Object> map : data.entrySet()) {
+            // 璁剧疆鍒楄〃鍚庣画杩樻湁鏁版嵁
+            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
+            if (map.getValue() instanceof Collection) {
+                // 澶氳〃瀵煎嚭蹇呴』浣跨敤 FillWrapper
+                excelWriter.fill(new FillWrapper(map.getKey(), (Collection<?>) map.getValue()), fillConfig, writeSheet);
+            } else {
+                excelWriter.fill(map.getValue(), writeSheet);
+            }
+        }
+        excelWriter.finish();
+    }
+
+    /**
+     * 閲嶇疆鍝嶅簲浣�
+     */
+    private static void resetResponse(String sheetName, HttpServletResponse response) {
+        String filename = encodingFilename(sheetName);
+        FileUtils.setAttachmentResponseHeader(response, filename);
+        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
+    }
+
+    /**
+     * 瑙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(StringUtils.SEPARATOR);
+        for (String item : convertSource) {
+            String[] itemArray = item.split("=");
+            if (StringUtils.containsAny(propertyValue, separator)) {
+                for (String value : propertyValue.split(separator)) {
+                    if (itemArray[0].equals(value)) {
+                        propertyString.append(itemArray[1]).append(separator);
+                        break;
+                    }
+                }
+            } else {
+                if (itemArray[0].equals(propertyValue)) {
+                    return itemArray[1];
+                }
+            }
+        }
+        return StringUtils.stripEnd(propertyString.toString(), separator);
+    }
+
+    /**
+     * 鍙嶅悜瑙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(StringUtils.SEPARATOR);
+        for (String item : convertSource) {
+            String[] itemArray = item.split("=");
+            if (StringUtils.containsAny(propertyValue, separator)) {
+                for (String value : propertyValue.split(separator)) {
+                    if (itemArray[1].equals(value)) {
+                        propertyString.append(itemArray[0]).append(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-common/ruoyi-common-idempotent/pom.xml b/ruoyi-common/ruoyi-common-idempotent/pom.xml
index 0445078..e6ba5e5 100644
--- a/ruoyi-common/ruoyi-common-idempotent/pom.xml
+++ b/ruoyi-common/ruoyi-common-idempotent/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-common</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -18,12 +18,12 @@
 
     <dependencies>
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-json</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-redis</artifactId>
         </dependency>
 
diff --git a/ruoyi-common/ruoyi-common-idempotent/src/main/java/com/ruoyi/common/idempotent/annotation/RepeatSubmit.java b/ruoyi-common/ruoyi-common-idempotent/src/main/java/com/ruoyi/common/idempotent/annotation/RepeatSubmit.java
deleted file mode 100644
index 8801e49..0000000
--- a/ruoyi-common/ruoyi-common-idempotent/src/main/java/com/ruoyi/common/idempotent/annotation/RepeatSubmit.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.ruoyi.common.idempotent.annotation;
-
-import java.lang.annotation.*;
-import java.util.concurrent.TimeUnit;
-
-/**
- * 鑷畾涔夋敞瑙i槻姝㈣〃鍗曢噸澶嶆彁浜�
- *
- * @author Lion Li
- */
-@Inherited
-@Target(ElementType.METHOD)
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-public @interface RepeatSubmit {
-
-    /**
-     * 闂撮殧鏃堕棿(ms)锛屽皬浜庢鏃堕棿瑙嗕负閲嶅鎻愪氦
-     */
-    int interval() default 5000;
-
-    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
-
-    /**
-     * 鎻愮ず娑堟伅 鏀寔鍥介檯鍖� 鏍煎紡涓� {code}
-     */
-    String message() default "{repeat.submit.message}";
-
-}
diff --git a/ruoyi-common/ruoyi-common-idempotent/src/main/java/com/ruoyi/common/idempotent/aspectj/RepeatSubmitAspect.java b/ruoyi-common/ruoyi-common-idempotent/src/main/java/com/ruoyi/common/idempotent/aspectj/RepeatSubmitAspect.java
deleted file mode 100644
index 37824d5..0000000
--- a/ruoyi-common/ruoyi-common-idempotent/src/main/java/com/ruoyi/common/idempotent/aspectj/RepeatSubmitAspect.java
+++ /dev/null
@@ -1,152 +0,0 @@
-package com.ruoyi.common.idempotent.aspectj;
-
-import cn.dev33.satoken.SaManager;
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.crypto.SecureUtil;
-import com.ruoyi.common.core.constant.GlobalConstants;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.utils.MessageUtils;
-import com.ruoyi.common.core.utils.ServletUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.idempotent.annotation.RepeatSubmit;
-import com.ruoyi.common.json.utils.JsonUtils;
-import com.ruoyi.common.redis.utils.RedisUtils;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import org.aspectj.lang.JoinPoint;
-import org.aspectj.lang.annotation.AfterReturning;
-import org.aspectj.lang.annotation.AfterThrowing;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Before;
-import org.springframework.validation.BindingResult;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.time.Duration;
-import java.util.Collection;
-import java.util.Map;
-
-/**
- * 闃叉閲嶅鎻愪氦(鍙傝�冪編鍥TIS闃查噸绯荤粺)
- *
- * @author Lion Li
- */
-@Aspect
-public class RepeatSubmitAspect {
-
-    private static final ThreadLocal<String> KEY_CACHE = new ThreadLocal<>();
-
-    @Before("@annotation(repeatSubmit)")
-    public void doBefore(JoinPoint point, RepeatSubmit repeatSubmit) throws Throwable {
-        // 濡傛灉娉ㄨВ涓嶄负0 鍒欎娇鐢ㄦ敞瑙f暟鍊�
-        long interval = 0;
-        if (repeatSubmit.interval() > 0) {
-            interval = repeatSubmit.timeUnit().toMillis(repeatSubmit.interval());
-        }
-        if (interval < 1000) {
-            throw new ServiceException("閲嶅鎻愪氦闂撮殧鏃堕棿涓嶈兘灏忎簬'1'绉�");
-        }
-        HttpServletRequest request = ServletUtils.getRequest();
-        String nowParams = argsArrayToString(point.getArgs());
-
-        // 璇锋眰鍦板潃锛堜綔涓哄瓨鏀綾ache鐨刱ey鍊硷級
-        String url = request.getRequestURI();
-
-        // 鍞竴鍊硷紙娌℃湁娑堟伅澶村垯浣跨敤璇锋眰鍦板潃锛�
-        String submitKey = StringUtils.trimToEmpty(request.getHeader(SaManager.getConfig().getTokenName()));
-
-        submitKey = SecureUtil.md5(submitKey + ":" + nowParams);
-        // 鍞竴鏍囪瘑锛堟寚瀹歬ey + url + 娑堟伅澶达級
-        String cacheRepeatKey = GlobalConstants.REPEAT_SUBMIT_KEY + url + submitKey;
-        String key = RedisUtils.getCacheObject(cacheRepeatKey);
-        if (key == null) {
-            RedisUtils.setCacheObject(cacheRepeatKey, "", Duration.ofMillis(interval));
-            KEY_CACHE.set(cacheRepeatKey);
-        } else {
-            String message = repeatSubmit.message();
-            if (StringUtils.startsWith(message, "{") && StringUtils.endsWith(message, "}")) {
-                message = MessageUtils.message(StringUtils.substring(message, 1, message.length() - 1));
-            }
-            throw new ServiceException(message);
-        }
-    }
-
-    /**
-     * 澶勭悊瀹岃姹傚悗鎵ц
-     *
-     * @param joinPoint 鍒囩偣
-     */
-    @AfterReturning(pointcut = "@annotation(repeatSubmit)", returning = "jsonResult")
-    public void doAfterReturning(JoinPoint joinPoint, RepeatSubmit repeatSubmit, Object jsonResult) {
-        if (jsonResult instanceof R r) {
-            try {
-                // 鎴愬姛鍒欎笉鍒犻櫎redis鏁版嵁 淇濊瘉鍦ㄦ湁鏁堟椂闂村唴鏃犳硶閲嶅鎻愪氦
-                if (r.getCode() == R.SUCCESS) {
-                    return;
-                }
-                RedisUtils.deleteObject(KEY_CACHE.get());
-            } finally {
-                KEY_CACHE.remove();
-            }
-        }
-    }
-
-    /**
-     * 鎷︽埅寮傚父鎿嶄綔
-     *
-     * @param joinPoint 鍒囩偣
-     * @param e         寮傚父
-     */
-    @AfterThrowing(value = "@annotation(repeatSubmit)", throwing = "e")
-    public void doAfterThrowing(JoinPoint joinPoint, RepeatSubmit repeatSubmit, Exception e) {
-        RedisUtils.deleteObject(KEY_CACHE.get());
-        KEY_CACHE.remove();
-    }
-
-    /**
-     * 鍙傛暟鎷艰
-     */
-    private String argsArrayToString(Object[] paramsArray) {
-        StringBuilder params = new StringBuilder();
-        if (paramsArray != null && paramsArray.length > 0) {
-            for (Object o : paramsArray) {
-                if (ObjectUtil.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-common/ruoyi-common-idempotent/src/main/java/com/ruoyi/common/idempotent/config/IdempotentConfig.java b/ruoyi-common/ruoyi-common-idempotent/src/main/java/com/ruoyi/common/idempotent/config/IdempotentConfig.java
deleted file mode 100644
index 79f8d14..0000000
--- a/ruoyi-common/ruoyi-common-idempotent/src/main/java/com/ruoyi/common/idempotent/config/IdempotentConfig.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.ruoyi.common.idempotent.config;
-
-import com.ruoyi.common.idempotent.aspectj.RepeatSubmitAspect;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.context.annotation.Bean;
-import org.springframework.data.redis.connection.RedisConfiguration;
-
-/**
- * 骞傜瓑鍔熻兘閰嶇疆
- *
- * @author Lion Li
- */
-@AutoConfiguration(after = RedisConfiguration.class)
-public class IdempotentConfig {
-
-    @Bean
-    public RepeatSubmitAspect repeatSubmitAspect() {
-        return new RepeatSubmitAspect();
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-idempotent/src/main/java/org/dromara/common/idempotent/annotation/RepeatSubmit.java b/ruoyi-common/ruoyi-common-idempotent/src/main/java/org/dromara/common/idempotent/annotation/RepeatSubmit.java
new file mode 100644
index 0000000..42ae802
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-idempotent/src/main/java/org/dromara/common/idempotent/annotation/RepeatSubmit.java
@@ -0,0 +1,29 @@
+package org.dromara.common.idempotent.annotation;
+
+import java.lang.annotation.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 鑷畾涔夋敞瑙i槻姝㈣〃鍗曢噸澶嶆彁浜�
+ *
+ * @author Lion Li
+ */
+@Inherited
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface RepeatSubmit {
+
+    /**
+     * 闂撮殧鏃堕棿(ms)锛屽皬浜庢鏃堕棿瑙嗕负閲嶅鎻愪氦
+     */
+    int interval() default 5000;
+
+    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
+
+    /**
+     * 鎻愮ず娑堟伅 鏀寔鍥介檯鍖� 鏍煎紡涓� {code}
+     */
+    String message() default "{repeat.submit.message}";
+
+}
diff --git a/ruoyi-common/ruoyi-common-idempotent/src/main/java/org/dromara/common/idempotent/aspectj/RepeatSubmitAspect.java b/ruoyi-common/ruoyi-common-idempotent/src/main/java/org/dromara/common/idempotent/aspectj/RepeatSubmitAspect.java
new file mode 100644
index 0000000..77f2646
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-idempotent/src/main/java/org/dromara/common/idempotent/aspectj/RepeatSubmitAspect.java
@@ -0,0 +1,152 @@
+package org.dromara.common.idempotent.aspectj;
+
+import cn.dev33.satoken.SaManager;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.crypto.SecureUtil;
+import org.dromara.common.core.constant.GlobalConstants;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.MessageUtils;
+import org.dromara.common.core.utils.ServletUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.json.utils.JsonUtils;
+import org.dromara.common.redis.utils.RedisUtils;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.AfterThrowing;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.time.Duration;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * 闃叉閲嶅鎻愪氦(鍙傝�冪編鍥TIS闃查噸绯荤粺)
+ *
+ * @author Lion Li
+ */
+@Aspect
+public class RepeatSubmitAspect {
+
+    private static final ThreadLocal<String> KEY_CACHE = new ThreadLocal<>();
+
+    @Before("@annotation(repeatSubmit)")
+    public void doBefore(JoinPoint point, RepeatSubmit repeatSubmit) throws Throwable {
+        // 濡傛灉娉ㄨВ涓嶄负0 鍒欎娇鐢ㄦ敞瑙f暟鍊�
+        long interval = 0;
+        if (repeatSubmit.interval() > 0) {
+            interval = repeatSubmit.timeUnit().toMillis(repeatSubmit.interval());
+        }
+        if (interval < 1000) {
+            throw new ServiceException("閲嶅鎻愪氦闂撮殧鏃堕棿涓嶈兘灏忎簬'1'绉�");
+        }
+        HttpServletRequest request = ServletUtils.getRequest();
+        String nowParams = argsArrayToString(point.getArgs());
+
+        // 璇锋眰鍦板潃锛堜綔涓哄瓨鏀綾ache鐨刱ey鍊硷級
+        String url = request.getRequestURI();
+
+        // 鍞竴鍊硷紙娌℃湁娑堟伅澶村垯浣跨敤璇锋眰鍦板潃锛�
+        String submitKey = StringUtils.trimToEmpty(request.getHeader(SaManager.getConfig().getTokenName()));
+
+        submitKey = SecureUtil.md5(submitKey + ":" + nowParams);
+        // 鍞竴鏍囪瘑锛堟寚瀹歬ey + url + 娑堟伅澶达級
+        String cacheRepeatKey = GlobalConstants.REPEAT_SUBMIT_KEY + url + submitKey;
+        String key = RedisUtils.getCacheObject(cacheRepeatKey);
+        if (key == null) {
+            RedisUtils.setCacheObject(cacheRepeatKey, "", Duration.ofMillis(interval));
+            KEY_CACHE.set(cacheRepeatKey);
+        } else {
+            String message = repeatSubmit.message();
+            if (StringUtils.startsWith(message, "{") && StringUtils.endsWith(message, "}")) {
+                message = MessageUtils.message(StringUtils.substring(message, 1, message.length() - 1));
+            }
+            throw new ServiceException(message);
+        }
+    }
+
+    /**
+     * 澶勭悊瀹岃姹傚悗鎵ц
+     *
+     * @param joinPoint 鍒囩偣
+     */
+    @AfterReturning(pointcut = "@annotation(repeatSubmit)", returning = "jsonResult")
+    public void doAfterReturning(JoinPoint joinPoint, RepeatSubmit repeatSubmit, Object jsonResult) {
+        if (jsonResult instanceof R r) {
+            try {
+                // 鎴愬姛鍒欎笉鍒犻櫎redis鏁版嵁 淇濊瘉鍦ㄦ湁鏁堟椂闂村唴鏃犳硶閲嶅鎻愪氦
+                if (r.getCode() == R.SUCCESS) {
+                    return;
+                }
+                RedisUtils.deleteObject(KEY_CACHE.get());
+            } finally {
+                KEY_CACHE.remove();
+            }
+        }
+    }
+
+    /**
+     * 鎷︽埅寮傚父鎿嶄綔
+     *
+     * @param joinPoint 鍒囩偣
+     * @param e         寮傚父
+     */
+    @AfterThrowing(value = "@annotation(repeatSubmit)", throwing = "e")
+    public void doAfterThrowing(JoinPoint joinPoint, RepeatSubmit repeatSubmit, Exception e) {
+        RedisUtils.deleteObject(KEY_CACHE.get());
+        KEY_CACHE.remove();
+    }
+
+    /**
+     * 鍙傛暟鎷艰
+     */
+    private String argsArrayToString(Object[] paramsArray) {
+        StringBuilder params = new StringBuilder();
+        if (paramsArray != null && paramsArray.length > 0) {
+            for (Object o : paramsArray) {
+                if (ObjectUtil.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-common/ruoyi-common-idempotent/src/main/java/org/dromara/common/idempotent/config/IdempotentConfig.java b/ruoyi-common/ruoyi-common-idempotent/src/main/java/org/dromara/common/idempotent/config/IdempotentConfig.java
new file mode 100644
index 0000000..fcb9d03
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-idempotent/src/main/java/org/dromara/common/idempotent/config/IdempotentConfig.java
@@ -0,0 +1,21 @@
+package org.dromara.common.idempotent.config;
+
+import org.dromara.common.idempotent.aspectj.RepeatSubmitAspect;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.data.redis.connection.RedisConfiguration;
+
+/**
+ * 骞傜瓑鍔熻兘閰嶇疆
+ *
+ * @author Lion Li
+ */
+@AutoConfiguration(after = RedisConfiguration.class)
+public class IdempotentConfig {
+
+    @Bean
+    public RepeatSubmitAspect repeatSubmitAspect() {
+        return new RepeatSubmitAspect();
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-idempotent/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-idempotent/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index 3541517..f2fa958 100644
--- a/ruoyi-common/ruoyi-common-idempotent/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-common/ruoyi-common-idempotent/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +1 @@
-com.ruoyi.common.idempotent.config.IdempotentConfig
+org.dromara.common.idempotent.config.IdempotentConfig
diff --git a/ruoyi-common/ruoyi-common-job/pom.xml b/ruoyi-common/ruoyi-common-job/pom.xml
index ea2b6d0..5acdfc5 100644
--- a/ruoyi-common/ruoyi-common-job/pom.xml
+++ b/ruoyi-common/ruoyi-common-job/pom.xml
@@ -3,7 +3,7 @@
          xmlns="http://maven.apache.org/POM/4.0.0"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <parent>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-common</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -35,7 +35,7 @@
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-core</artifactId>
         </dependency>
 
diff --git a/ruoyi-common/ruoyi-common-job/src/main/java/com/ruoyi/common/job/config/XxlJobConfig.java b/ruoyi-common/ruoyi-common-job/src/main/java/com/ruoyi/common/job/config/XxlJobConfig.java
deleted file mode 100644
index 34191f1..0000000
--- a/ruoyi-common/ruoyi-common-job/src/main/java/com/ruoyi/common/job/config/XxlJobConfig.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.ruoyi.common.job.config;
-
-import com.ruoyi.common.job.config.properties.XxlJobProperties;
-import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-
-/**
- * xxl-job config
- *
- * @author Lion Li
- */
-@Slf4j
-@AutoConfiguration
-@EnableConfigurationProperties(XxlJobProperties.class)
-@ConditionalOnProperty(prefix = "xxl.job", name = "enabled", havingValue = "true")
-public class XxlJobConfig {
-
-    @Bean
-    public XxlJobSpringExecutor xxlJobExecutor(XxlJobProperties xxlJobProperties) {
-        log.info(">>>>>>>>>>> xxl-job config init.");
-        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
-        xxlJobSpringExecutor.setAdminAddresses(xxlJobProperties.getAdminAddresses());
-        xxlJobSpringExecutor.setAccessToken(xxlJobProperties.getAccessToken());
-        XxlJobProperties.Executor executor = xxlJobProperties.getExecutor();
-        xxlJobSpringExecutor.setAppname(executor.getAppname());
-        xxlJobSpringExecutor.setAddress(executor.getAddress());
-        xxlJobSpringExecutor.setIp(executor.getIp());
-        xxlJobSpringExecutor.setPort(executor.getPort());
-        xxlJobSpringExecutor.setLogPath(executor.getLogPath());
-        xxlJobSpringExecutor.setLogRetentionDays(executor.getLogRetentionDays());
-        return xxlJobSpringExecutor;
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-job/src/main/java/com/ruoyi/common/job/config/properties/XxlJobProperties.java b/ruoyi-common/ruoyi-common-job/src/main/java/com/ruoyi/common/job/config/properties/XxlJobProperties.java
deleted file mode 100644
index fc89a2f..0000000
--- a/ruoyi-common/ruoyi-common-job/src/main/java/com/ruoyi/common/job/config/properties/XxlJobProperties.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.ruoyi.common.job.config.properties;
-
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-/**
- * xxljob閰嶇疆绫�
- *
- * @author Lion Li
- */
-@Data
-@ConfigurationProperties(prefix = "xxl.job")
-public class XxlJobProperties {
-
-    private Boolean enabled;
-
-    private String adminAddresses;
-
-    private String accessToken;
-
-    private Executor executor;
-
-    @Data
-    @NoArgsConstructor
-    public static class Executor {
-
-        private String appname;
-
-        private String address;
-
-        private String ip;
-
-        private int port;
-
-        private String logPath;
-
-        private int logRetentionDays;
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/XxlJobConfig.java b/ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/XxlJobConfig.java
new file mode 100644
index 0000000..f85c805
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/XxlJobConfig.java
@@ -0,0 +1,38 @@
+package org.dromara.common.job.config;
+
+import org.dromara.common.job.config.properties.XxlJobProperties;
+import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * xxl-job config
+ *
+ * @author Lion Li
+ */
+@Slf4j
+@AutoConfiguration
+@EnableConfigurationProperties(XxlJobProperties.class)
+@ConditionalOnProperty(prefix = "xxl.job", name = "enabled", havingValue = "true")
+public class XxlJobConfig {
+
+    @Bean
+    public XxlJobSpringExecutor xxlJobExecutor(XxlJobProperties xxlJobProperties) {
+        log.info(">>>>>>>>>>> xxl-job config init.");
+        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
+        xxlJobSpringExecutor.setAdminAddresses(xxlJobProperties.getAdminAddresses());
+        xxlJobSpringExecutor.setAccessToken(xxlJobProperties.getAccessToken());
+        XxlJobProperties.Executor executor = xxlJobProperties.getExecutor();
+        xxlJobSpringExecutor.setAppname(executor.getAppname());
+        xxlJobSpringExecutor.setAddress(executor.getAddress());
+        xxlJobSpringExecutor.setIp(executor.getIp());
+        xxlJobSpringExecutor.setPort(executor.getPort());
+        xxlJobSpringExecutor.setLogPath(executor.getLogPath());
+        xxlJobSpringExecutor.setLogRetentionDays(executor.getLogRetentionDays());
+        return xxlJobSpringExecutor;
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/properties/XxlJobProperties.java b/ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/properties/XxlJobProperties.java
new file mode 100644
index 0000000..47cbc2c
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/properties/XxlJobProperties.java
@@ -0,0 +1,40 @@
+package org.dromara.common.job.config.properties;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * xxljob閰嶇疆绫�
+ *
+ * @author Lion Li
+ */
+@Data
+@ConfigurationProperties(prefix = "xxl.job")
+public class XxlJobProperties {
+
+    private Boolean enabled;
+
+    private String adminAddresses;
+
+    private String accessToken;
+
+    private Executor executor;
+
+    @Data
+    @NoArgsConstructor
+    public static class Executor {
+
+        private String appname;
+
+        private String address;
+
+        private String ip;
+
+        private int port;
+
+        private String logPath;
+
+        private int logRetentionDays;
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-job/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-job/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index dfcf8a6..3e6fd6e 100644
--- a/ruoyi-common/ruoyi-common-job/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-common/ruoyi-common-job/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +1 @@
-com.ruoyi.common.job.config.XxlJobConfig
+org.dromara.common.job.config.XxlJobConfig
diff --git a/ruoyi-common/ruoyi-common-json/pom.xml b/ruoyi-common/ruoyi-common-json/pom.xml
index 29350ba..c46be17 100644
--- a/ruoyi-common/ruoyi-common-json/pom.xml
+++ b/ruoyi-common/ruoyi-common-json/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-common</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -18,7 +18,7 @@
 
     <dependencies>
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-core</artifactId>
         </dependency>
 
diff --git a/ruoyi-common/ruoyi-common-json/src/main/java/com/ruoyi/common/json/config/JacksonConfig.java b/ruoyi-common/ruoyi-common-json/src/main/java/com/ruoyi/common/json/config/JacksonConfig.java
deleted file mode 100644
index 6b09b47..0000000
--- a/ruoyi-common/ruoyi-common-json/src/main/java/com/ruoyi/common/json/config/JacksonConfig.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.ruoyi.common.json.config;
-
-import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
-import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
-import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
-import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
-import com.ruoyi.common.json.handler.BigNumberSerializer;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
-import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
-import org.springframework.context.annotation.Bean;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.TimeZone;
-
-/**
- * jackson 閰嶇疆
- *
- * @author Lion Li
- */
-@Slf4j
-@AutoConfiguration(before = JacksonAutoConfiguration.class)
-public class JacksonConfig {
-
-    @Bean
-    public Jackson2ObjectMapperBuilderCustomizer customizer() {
-        return builder -> {
-            // 鍏ㄥ眬閰嶇疆搴忓垪鍖栬繑鍥� JSON 澶勭悊
-            JavaTimeModule javaTimeModule = new JavaTimeModule();
-            javaTimeModule.addSerializer(Long.class, BigNumberSerializer.INSTANCE);
-            javaTimeModule.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE);
-            javaTimeModule.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE);
-            javaTimeModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);
-            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
-            javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
-            javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
-            builder.modules(javaTimeModule);
-            builder.timeZone(TimeZone.getDefault());
-            log.info("鍒濆鍖� jackson 閰嶇疆");
-        };
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-json/src/main/java/com/ruoyi/common/json/handler/BigNumberSerializer.java b/ruoyi-common/ruoyi-common-json/src/main/java/com/ruoyi/common/json/handler/BigNumberSerializer.java
deleted file mode 100644
index bb797b3..0000000
--- a/ruoyi-common/ruoyi-common-json/src/main/java/com/ruoyi/common/json/handler/BigNumberSerializer.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.ruoyi.common.json.handler;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
-import com.fasterxml.jackson.databind.ser.std.NumberSerializer;
-
-import java.io.IOException;
-
-/**
- * 瓒呭嚭 JS 鏈�澶ф渶灏忓�� 澶勭悊
- *
- * @author Lion Li
- */
-@JacksonStdImpl
-public class BigNumberSerializer extends NumberSerializer {
-
-    /**
-     * 鏍规嵁 JS Number.MAX_SAFE_INTEGER 涓� Number.MIN_SAFE_INTEGER 寰楁潵
-     */
-    private static final long MAX_SAFE_INTEGER = 9007199254740991L;
-    private static final long MIN_SAFE_INTEGER = -9007199254740991L;
-
-    /**
-     * 鎻愪緵瀹炰緥
-     */
-    public static final BigNumberSerializer INSTANCE = new BigNumberSerializer(Number.class);
-
-    public BigNumberSerializer(Class<? extends Number> rawType) {
-        super(rawType);
-    }
-
-    @Override
-    public void serialize(Number value, JsonGenerator gen, SerializerProvider provider) throws IOException {
-        // 瓒呭嚭鑼冨洿 搴忓垪鍖栦綅瀛楃涓�
-        if (value.longValue() > MIN_SAFE_INTEGER && value.longValue() < MAX_SAFE_INTEGER) {
-            super.serialize(value, gen, provider);
-        } else {
-            gen.writeString(value.toString());
-        }
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-json/src/main/java/com/ruoyi/common/json/utils/JsonUtils.java b/ruoyi-common/ruoyi-common-json/src/main/java/com/ruoyi/common/json/utils/JsonUtils.java
deleted file mode 100644
index 66a63a2..0000000
--- a/ruoyi-common/ruoyi-common-json/src/main/java/com/ruoyi/common/json/utils/JsonUtils.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package com.ruoyi.common.json.utils;
-
-import cn.hutool.core.lang.Dict;
-import cn.hutool.core.util.ArrayUtil;
-import cn.hutool.core.util.ObjectUtil;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.exc.MismatchedInputException;
-import com.ruoyi.common.core.utils.SpringUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * JSON 宸ュ叿绫�
- *
- * @author 鑺嬮亾婧愮爜
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class JsonUtils {
-
-    private static final ObjectMapper OBJECT_MAPPER = SpringUtils.getBean(ObjectMapper.class);
-
-    public static ObjectMapper getObjectMapper() {
-        return OBJECT_MAPPER;
-    }
-
-    public static String toJsonString(Object object) {
-        if (ObjectUtil.isNull(object)) {
-            return null;
-        }
-        try {
-            return OBJECT_MAPPER.writeValueAsString(object);
-        } catch (JsonProcessingException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public static <T> T parseObject(String text, Class<T> clazz) {
-        if (StringUtils.isEmpty(text)) {
-            return null;
-        }
-        try {
-            return OBJECT_MAPPER.readValue(text, clazz);
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public static <T> T parseObject(byte[] bytes, Class<T> clazz) {
-        if (ArrayUtil.isEmpty(bytes)) {
-            return null;
-        }
-        try {
-            return OBJECT_MAPPER.readValue(bytes, clazz);
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public static <T> T parseObject(String text, TypeReference<T> typeReference) {
-        if (StringUtils.isBlank(text)) {
-            return null;
-        }
-        try {
-            return OBJECT_MAPPER.readValue(text, typeReference);
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public static Dict parseMap(String text) {
-        if (StringUtils.isBlank(text)) {
-            return null;
-        }
-        try {
-            return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructType(Dict.class));
-        } catch (MismatchedInputException e) {
-            // 绫诲瀷涓嶅尮閰嶈鏄庝笉鏄痡son
-            return null;
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public static List<Dict> parseArrayMap(String text) {
-        if (StringUtils.isBlank(text)) {
-            return null;
-        }
-        try {
-            return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, Dict.class));
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public static <T> List<T> parseArray(String text, Class<T> clazz) {
-        if (StringUtils.isEmpty(text)) {
-            return new ArrayList<>();
-        }
-        try {
-            return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/config/JacksonConfig.java b/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/config/JacksonConfig.java
new file mode 100644
index 0000000..8f5a45d
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/config/JacksonConfig.java
@@ -0,0 +1,47 @@
+package org.dromara.common.json.config;
+
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import org.dromara.common.json.handler.BigNumberSerializer;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
+import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.TimeZone;
+
+/**
+ * jackson 閰嶇疆
+ *
+ * @author Lion Li
+ */
+@Slf4j
+@AutoConfiguration(before = JacksonAutoConfiguration.class)
+public class JacksonConfig {
+
+    @Bean
+    public Jackson2ObjectMapperBuilderCustomizer customizer() {
+        return builder -> {
+            // 鍏ㄥ眬閰嶇疆搴忓垪鍖栬繑鍥� JSON 澶勭悊
+            JavaTimeModule javaTimeModule = new JavaTimeModule();
+            javaTimeModule.addSerializer(Long.class, BigNumberSerializer.INSTANCE);
+            javaTimeModule.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE);
+            javaTimeModule.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE);
+            javaTimeModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+            javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
+            javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
+            builder.modules(javaTimeModule);
+            builder.timeZone(TimeZone.getDefault());
+            log.info("鍒濆鍖� jackson 閰嶇疆");
+        };
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/handler/BigNumberSerializer.java b/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/handler/BigNumberSerializer.java
new file mode 100644
index 0000000..f2a7c2d
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/handler/BigNumberSerializer.java
@@ -0,0 +1,42 @@
+package org.dromara.common.json.handler;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
+import com.fasterxml.jackson.databind.ser.std.NumberSerializer;
+
+import java.io.IOException;
+
+/**
+ * 瓒呭嚭 JS 鏈�澶ф渶灏忓�� 澶勭悊
+ *
+ * @author Lion Li
+ */
+@JacksonStdImpl
+public class BigNumberSerializer extends NumberSerializer {
+
+    /**
+     * 鏍规嵁 JS Number.MAX_SAFE_INTEGER 涓� Number.MIN_SAFE_INTEGER 寰楁潵
+     */
+    private static final long MAX_SAFE_INTEGER = 9007199254740991L;
+    private static final long MIN_SAFE_INTEGER = -9007199254740991L;
+
+    /**
+     * 鎻愪緵瀹炰緥
+     */
+    public static final BigNumberSerializer INSTANCE = new BigNumberSerializer(Number.class);
+
+    public BigNumberSerializer(Class<? extends Number> rawType) {
+        super(rawType);
+    }
+
+    @Override
+    public void serialize(Number value, JsonGenerator gen, SerializerProvider provider) throws IOException {
+        // 瓒呭嚭鑼冨洿 搴忓垪鍖栦綅瀛楃涓�
+        if (value.longValue() > MIN_SAFE_INTEGER && value.longValue() < MAX_SAFE_INTEGER) {
+            super.serialize(value, gen, provider);
+        } else {
+            gen.writeString(value.toString());
+        }
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/utils/JsonUtils.java b/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/utils/JsonUtils.java
new file mode 100644
index 0000000..42af8da
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/utils/JsonUtils.java
@@ -0,0 +1,113 @@
+package org.dromara.common.json.utils;
+
+import cn.hutool.core.lang.Dict;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.exc.MismatchedInputException;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.StringUtils;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * JSON 宸ュ叿绫�
+ *
+ * @author 鑺嬮亾婧愮爜
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class JsonUtils {
+
+    private static final ObjectMapper OBJECT_MAPPER = SpringUtils.getBean(ObjectMapper.class);
+
+    public static ObjectMapper getObjectMapper() {
+        return OBJECT_MAPPER;
+    }
+
+    public static String toJsonString(Object object) {
+        if (ObjectUtil.isNull(object)) {
+            return null;
+        }
+        try {
+            return OBJECT_MAPPER.writeValueAsString(object);
+        } catch (JsonProcessingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static <T> T parseObject(String text, Class<T> clazz) {
+        if (StringUtils.isEmpty(text)) {
+            return null;
+        }
+        try {
+            return OBJECT_MAPPER.readValue(text, clazz);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static <T> T parseObject(byte[] bytes, Class<T> clazz) {
+        if (ArrayUtil.isEmpty(bytes)) {
+            return null;
+        }
+        try {
+            return OBJECT_MAPPER.readValue(bytes, clazz);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static <T> T parseObject(String text, TypeReference<T> typeReference) {
+        if (StringUtils.isBlank(text)) {
+            return null;
+        }
+        try {
+            return OBJECT_MAPPER.readValue(text, typeReference);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static Dict parseMap(String text) {
+        if (StringUtils.isBlank(text)) {
+            return null;
+        }
+        try {
+            return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructType(Dict.class));
+        } catch (MismatchedInputException e) {
+            // 绫诲瀷涓嶅尮閰嶈鏄庝笉鏄痡son
+            return null;
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static List<Dict> parseArrayMap(String text) {
+        if (StringUtils.isBlank(text)) {
+            return null;
+        }
+        try {
+            return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, Dict.class));
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static <T> List<T> parseArray(String text, Class<T> clazz) {
+        if (StringUtils.isEmpty(text)) {
+            return new ArrayList<>();
+        }
+        try {
+            return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-json/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-json/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index 6847712..1625397 100644
--- a/ruoyi-common/ruoyi-common-json/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-common/ruoyi-common-json/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +1 @@
-com.ruoyi.common.json.config.JacksonConfig
+org.dromara.common.json.config.JacksonConfig
diff --git a/ruoyi-common/ruoyi-common-log/pom.xml b/ruoyi-common/ruoyi-common-log/pom.xml
index be70731..8ed86ad 100644
--- a/ruoyi-common/ruoyi-common-log/pom.xml
+++ b/ruoyi-common/ruoyi-common-log/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-common</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -19,12 +19,12 @@
     <dependencies>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-satoken</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-json</artifactId>
         </dependency>
 
diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/annotation/Log.java b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/annotation/Log.java
deleted file mode 100644
index 4e5fc58..0000000
--- a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/annotation/Log.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.ruoyi.common.log.annotation;
-
-import com.ruoyi.common.log.enums.BusinessType;
-import com.ruoyi.common.log.enums.OperatorType;
-
-import java.lang.annotation.*;
-
-/**
- * 鑷畾涔夋搷浣滄棩蹇楄褰曟敞瑙�
- *
- * @author ruoyi
- */
-@Target({ElementType.PARAMETER, ElementType.METHOD})
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-public @interface Log {
-    /**
-     * 妯″潡
-     */
-    String title() default "";
-
-    /**
-     * 鍔熻兘
-     */
-    BusinessType businessType() default BusinessType.OTHER;
-
-    /**
-     * 鎿嶄綔浜虹被鍒�
-     */
-    OperatorType operatorType() default OperatorType.MANAGE;
-
-    /**
-     * 鏄惁淇濆瓨璇锋眰鐨勫弬鏁�
-     */
-    boolean isSaveRequestData() default true;
-
-    /**
-     * 鏄惁淇濆瓨鍝嶅簲鐨勫弬鏁�
-     */
-    boolean isSaveResponseData() default true;
-
-
-    /**
-     * 鎺掗櫎鎸囧畾鐨勮姹傚弬鏁�
-     */
-    String[] excludeParamNames() default {};
-
-}
diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/aspect/LogAspect.java b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/aspect/LogAspect.java
deleted file mode 100644
index 4aba4ec..0000000
--- a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/aspect/LogAspect.java
+++ /dev/null
@@ -1,221 +0,0 @@
-package com.ruoyi.common.log.aspect;
-
-import cn.hutool.core.lang.Dict;
-import cn.hutool.core.map.MapUtil;
-import cn.hutool.core.util.ObjectUtil;
-import com.alibaba.ttl.TransmittableThreadLocal;
-import com.ruoyi.common.core.utils.ServletUtils;
-import com.ruoyi.common.core.utils.SpringUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.json.utils.JsonUtils;
-import com.ruoyi.common.log.annotation.Log;
-import com.ruoyi.common.log.enums.BusinessStatus;
-import com.ruoyi.common.log.event.OperLogEvent;
-import com.ruoyi.common.satoken.utils.LoginHelper;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.time.StopWatch;
-import org.aspectj.lang.JoinPoint;
-import org.aspectj.lang.annotation.AfterReturning;
-import org.aspectj.lang.annotation.AfterThrowing;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Before;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.http.HttpMethod;
-import org.springframework.validation.BindingResult;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.util.Collection;
-import java.util.Map;
-
-/**
- * 鎿嶄綔鏃ュ織璁板綍澶勭悊
- *
- * @author Lion Li
- */
-@Slf4j
-@Aspect
-@AutoConfiguration
-public class LogAspect {
-
-    /**
-     * 鎺掗櫎鏁忔劅灞炴�у瓧娈�
-     */
-    public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" };
-
-
-    /**
-     * 璁$畻鎿嶄綔娑堣�楁椂闂�
-     */
-    private static final ThreadLocal<StopWatch> TIME_THREADLOCAL = new TransmittableThreadLocal<>();
-
-    /**
-     * 澶勭悊璇锋眰鍓嶆墽琛�
-     */
-    @Before(value = "@annotation(controllerLog)")
-    public void boBefore(JoinPoint joinPoint, Log controllerLog) {
-        StopWatch stopWatch = new StopWatch();
-        TIME_THREADLOCAL.set(stopWatch);
-        stopWatch.start();
-    }
-
-    /**
-     * 澶勭悊瀹岃姹傚悗鎵ц
-     *
-     * @param joinPoint 鍒囩偣
-     */
-    @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")
-    public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) {
-        handleLog(joinPoint, controllerLog, null, jsonResult);
-    }
-
-    /**
-     * 鎷︽埅寮傚父鎿嶄綔
-     *
-     * @param joinPoint 鍒囩偣
-     * @param e         寮傚父
-     */
-    @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")
-    public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) {
-        handleLog(joinPoint, controllerLog, e, null);
-    }
-
-    protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) {
-        try {
-
-            // *========鏁版嵁搴撴棩蹇�=========*//
-            OperLogEvent operLog = new OperLogEvent();
-            operLog.setTenantId(LoginHelper.getTenantId());
-            operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
-            // 璇锋眰鐨勫湴鍧�
-            String ip = ServletUtils.getClientIP();
-            operLog.setOperIp(ip);
-            operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255));
-            operLog.setOperName(LoginHelper.getUsername());
-
-            if (e != null) {
-                operLog.setStatus(BusinessStatus.FAIL.ordinal());
-                operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
-            }
-            // 璁剧疆鏂规硶鍚嶇О
-            String className = joinPoint.getTarget().getClass().getName();
-            String methodName = joinPoint.getSignature().getName();
-            operLog.setMethod(className + "." + methodName + "()");
-            // 璁剧疆璇锋眰鏂瑰紡
-            operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
-            // 澶勭悊璁剧疆娉ㄨВ涓婄殑鍙傛暟
-            getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
-            // 璁剧疆娑堣�楁椂闂�
-            StopWatch stopWatch = TIME_THREADLOCAL.get();
-            stopWatch.stop();
-            operLog.setCostTime(stopWatch.getTime());
-            // 鍙戝竷浜嬩欢淇濆瓨鏁版嵁搴�
-            SpringUtils.context().publishEvent(operLog);
-        } catch (Exception exp) {
-            // 璁板綍鏈湴寮傚父鏃ュ織
-            log.error("寮傚父淇℃伅:{}", exp.getMessage());
-            exp.printStackTrace();
-        } finally {
-            TIME_THREADLOCAL.remove();
-        }
-    }
-
-    /**
-     * 鑾峰彇娉ㄨВ涓鏂规硶鐨勬弿杩颁俊鎭� 鐢ㄤ簬Controller灞傛敞瑙�
-     *
-     * @param log     鏃ュ織
-     * @param operLog 鎿嶄綔鏃ュ織
-     * @throws Exception
-     */
-    public void getControllerMethodDescription(JoinPoint joinPoint, Log log, OperLogEvent operLog, Object jsonResult) throws Exception {
-        // 璁剧疆action鍔ㄤ綔
-        operLog.setBusinessType(log.businessType().ordinal());
-        // 璁剧疆鏍囬
-        operLog.setTitle(log.title());
-        // 璁剧疆鎿嶄綔浜虹被鍒�
-        operLog.setOperatorType(log.operatorType().ordinal());
-        // 鏄惁闇�瑕佷繚瀛榬equest锛屽弬鏁板拰鍊�
-        if (log.isSaveRequestData()) {
-            // 鑾峰彇鍙傛暟鐨勪俊鎭紝浼犲叆鍒版暟鎹簱涓��
-            setRequestValue(joinPoint, operLog, log.excludeParamNames());
-        }
-        // 鏄惁闇�瑕佷繚瀛榬esponse锛屽弬鏁板拰鍊�
-        if (log.isSaveResponseData() && ObjectUtil.isNotNull(jsonResult)) {
-            operLog.setJsonResult(StringUtils.substring(JsonUtils.toJsonString(jsonResult), 0, 2000));
-        }
-    }
-
-    /**
-     * 鑾峰彇璇锋眰鐨勫弬鏁帮紝鏀惧埌log涓�
-     *
-     * @param operLog 鎿嶄綔鏃ュ織
-     * @throws Exception 寮傚父
-     */
-    private void setRequestValue(JoinPoint joinPoint, OperLogEvent operLog, String[] excludeParamNames) throws Exception {
-        Map<String, String> paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest());
-        String requestMethod = operLog.getRequestMethod();
-        if (MapUtil.isEmpty(paramsMap)
-                && HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) {
-            String params = argsArrayToString(joinPoint.getArgs(), excludeParamNames);
-            operLog.setOperParam(StringUtils.substring(params, 0, 2000));
-        } else {
-            MapUtil.removeAny(paramsMap, EXCLUDE_PROPERTIES);
-            MapUtil.removeAny(paramsMap, excludeParamNames);
-            operLog.setOperParam(StringUtils.substring(JsonUtils.toJsonString(paramsMap), 0, 2000));
-        }
-    }
-
-    /**
-     * 鍙傛暟鎷艰
-     */
-    private String argsArrayToString(Object[] paramsArray, String[] excludeParamNames) {
-        StringBuilder params = new StringBuilder();
-        if (paramsArray != null && paramsArray.length > 0) {
-            for (Object o : paramsArray) {
-                if (ObjectUtil.isNotNull(o) && !isFilterObject(o)) {
-                    try {
-                        String str = JsonUtils.toJsonString(o);
-                        Dict dict = JsonUtils.parseMap(str);
-                        if (MapUtil.isNotEmpty(dict)) {
-                            MapUtil.removeAny(dict, EXCLUDE_PROPERTIES);
-                            MapUtil.removeAny(dict, excludeParamNames);
-                            str = JsonUtils.toJsonString(dict);
-                        }
-                        params.append(str).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-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/enums/BusinessStatus.java b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/enums/BusinessStatus.java
deleted file mode 100644
index 716c4cc..0000000
--- a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/enums/BusinessStatus.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.ruoyi.common.log.enums;
-
-/**
- * 鎿嶄綔鐘舵��
- *
- * @author ruoyi
- */
-public enum BusinessStatus {
-    /**
-     * 鎴愬姛
-     */
-    SUCCESS,
-
-    /**
-     * 澶辫触
-     */
-    FAIL,
-}
diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/enums/BusinessType.java b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/enums/BusinessType.java
deleted file mode 100644
index 7314de5..0000000
--- a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/enums/BusinessType.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package com.ruoyi.common.log.enums;
-
-/**
- * 涓氬姟鎿嶄綔绫诲瀷
- *
- * @author ruoyi
- */
-public enum BusinessType {
-    /**
-     * 鍏跺畠
-     */
-    OTHER,
-
-    /**
-     * 鏂板
-     */
-    INSERT,
-
-    /**
-     * 淇敼
-     */
-    UPDATE,
-
-    /**
-     * 鍒犻櫎
-     */
-    DELETE,
-
-    /**
-     * 鎺堟潈
-     */
-    GRANT,
-
-    /**
-     * 瀵煎嚭
-     */
-    EXPORT,
-
-    /**
-     * 瀵煎叆
-     */
-    IMPORT,
-
-    /**
-     * 寮洪��
-     */
-    FORCE,
-
-    /**
-     * 鐢熸垚浠g爜
-     */
-    GENCODE,
-
-    /**
-     * 娓呯┖鏁版嵁
-     */
-    CLEAN,
-}
diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/enums/OperatorType.java b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/enums/OperatorType.java
deleted file mode 100644
index a93394a..0000000
--- a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/enums/OperatorType.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.ruoyi.common.log.enums;
-
-/**
- * 鎿嶄綔浜虹被鍒�
- *
- * @author ruoyi
- */
-public enum OperatorType {
-    /**
-     * 鍏跺畠
-     */
-    OTHER,
-
-    /**
-     * 鍚庡彴鐢ㄦ埛
-     */
-    MANAGE,
-
-    /**
-     * 鎵嬫満绔敤鎴�
-     */
-    MOBILE
-}
diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/event/LogininforEvent.java b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/event/LogininforEvent.java
deleted file mode 100644
index 785f589..0000000
--- a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/event/LogininforEvent.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.ruoyi.common.log.event;
-
-import lombok.Data;
-
-import jakarta.servlet.http.HttpServletRequest;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-/**
- * 鐧诲綍浜嬩欢
- *
- * @author Lion Li
- */
-
-@Data
-public class LogininforEvent implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 绉熸埛ID
-     */
-    private String tenantId;
-
-    /**
-     * 鐢ㄦ埛璐﹀彿
-     */
-    private String username;
-
-    /**
-     * 鐧诲綍鐘舵�� 0鎴愬姛 1澶辫触
-     */
-    private String status;
-
-    /**
-     * 鎻愮ず娑堟伅
-     */
-    private String message;
-
-    /**
-     * 璇锋眰浣�
-     */
-    private HttpServletRequest request;
-
-    /**
-     * 鍏朵粬鍙傛暟
-     */
-    private Object[] args;
-
-}
diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/event/OperLogEvent.java b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/event/OperLogEvent.java
deleted file mode 100644
index 683cb41..0000000
--- a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/event/OperLogEvent.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package com.ruoyi.common.log.event;
-
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-
-/**
- * 鎿嶄綔鏃ュ織浜嬩欢
- *
- * @author Lion Li
- */
-
-@Data
-public class OperLogEvent implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 鏃ュ織涓婚敭
-     */
-    private Long operId;
-
-    /**
-     * 绉熸埛ID
-     */
-    private String tenantId;
-
-    /**
-     * 鎿嶄綔妯″潡
-     */
-    private String title;
-
-    /**
-     * 涓氬姟绫诲瀷锛�0鍏跺畠 1鏂板 2淇敼 3鍒犻櫎锛�
-     */
-    private Integer businessType;
-
-    /**
-     * 涓氬姟绫诲瀷鏁扮粍
-     */
-    private Integer[] businessTypes;
-
-    /**
-     * 璇锋眰鏂规硶
-     */
-    private String method;
-
-    /**
-     * 璇锋眰鏂瑰紡
-     */
-    private String requestMethod;
-
-    /**
-     * 鎿嶄綔绫诲埆锛�0鍏跺畠 1鍚庡彴鐢ㄦ埛 2鎵嬫満绔敤鎴凤級
-     */
-    private Integer operatorType;
-
-    /**
-     * 鎿嶄綔浜哄憳
-     */
-    private String operName;
-
-    /**
-     * 閮ㄩ棬鍚嶇О
-     */
-    private String deptName;
-
-    /**
-     * 璇锋眰url
-     */
-    private String operUrl;
-
-    /**
-     * 鎿嶄綔鍦板潃
-     */
-    private String operIp;
-
-    /**
-     * 鎿嶄綔鍦扮偣
-     */
-    private String operLocation;
-
-    /**
-     * 璇锋眰鍙傛暟
-     */
-    private String operParam;
-
-    /**
-     * 杩斿洖鍙傛暟
-     */
-    private String jsonResult;
-
-    /**
-     * 鎿嶄綔鐘舵�侊紙0姝e父 1寮傚父锛�
-     */
-    private Integer status;
-
-    /**
-     * 閿欒娑堟伅
-     */
-    private String errorMsg;
-
-    /**
-     * 鎿嶄綔鏃堕棿
-     */
-    private Date operTime;
-
-    /**
-     * 娑堣�楁椂闂�
-     */
-    private Long costTime;
-}
diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/annotation/Log.java b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/annotation/Log.java
new file mode 100644
index 0000000..2dced97
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/annotation/Log.java
@@ -0,0 +1,48 @@
+package org.dromara.common.log.annotation;
+
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.log.enums.OperatorType;
+
+import java.lang.annotation.*;
+
+/**
+ * 鑷畾涔夋搷浣滄棩蹇楄褰曟敞瑙�
+ *
+ * @author ruoyi
+ */
+@Target({ElementType.PARAMETER, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Log {
+    /**
+     * 妯″潡
+     */
+    String title() default "";
+
+    /**
+     * 鍔熻兘
+     */
+    BusinessType businessType() default BusinessType.OTHER;
+
+    /**
+     * 鎿嶄綔浜虹被鍒�
+     */
+    OperatorType operatorType() default OperatorType.MANAGE;
+
+    /**
+     * 鏄惁淇濆瓨璇锋眰鐨勫弬鏁�
+     */
+    boolean isSaveRequestData() default true;
+
+    /**
+     * 鏄惁淇濆瓨鍝嶅簲鐨勫弬鏁�
+     */
+    boolean isSaveResponseData() default true;
+
+
+    /**
+     * 鎺掗櫎鎸囧畾鐨勮姹傚弬鏁�
+     */
+    String[] excludeParamNames() default {};
+
+}
diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/aspect/LogAspect.java b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/aspect/LogAspect.java
new file mode 100644
index 0000000..dc3b9d0
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/aspect/LogAspect.java
@@ -0,0 +1,221 @@
+package org.dromara.common.log.aspect;
+
+import cn.hutool.core.lang.Dict;
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.ttl.TransmittableThreadLocal;
+import org.dromara.common.core.utils.ServletUtils;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.json.utils.JsonUtils;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessStatus;
+import org.dromara.common.log.event.OperLogEvent;
+import org.dromara.common.satoken.utils.LoginHelper;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.time.StopWatch;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.AfterThrowing;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.http.HttpMethod;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * 鎿嶄綔鏃ュ織璁板綍澶勭悊
+ *
+ * @author Lion Li
+ */
+@Slf4j
+@Aspect
+@AutoConfiguration
+public class LogAspect {
+
+    /**
+     * 鎺掗櫎鏁忔劅灞炴�у瓧娈�
+     */
+    public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" };
+
+
+    /**
+     * 璁$畻鎿嶄綔娑堣�楁椂闂�
+     */
+    private static final ThreadLocal<StopWatch> TIME_THREADLOCAL = new TransmittableThreadLocal<>();
+
+    /**
+     * 澶勭悊璇锋眰鍓嶆墽琛�
+     */
+    @Before(value = "@annotation(controllerLog)")
+    public void boBefore(JoinPoint joinPoint, Log controllerLog) {
+        StopWatch stopWatch = new StopWatch();
+        TIME_THREADLOCAL.set(stopWatch);
+        stopWatch.start();
+    }
+
+    /**
+     * 澶勭悊瀹岃姹傚悗鎵ц
+     *
+     * @param joinPoint 鍒囩偣
+     */
+    @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")
+    public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) {
+        handleLog(joinPoint, controllerLog, null, jsonResult);
+    }
+
+    /**
+     * 鎷︽埅寮傚父鎿嶄綔
+     *
+     * @param joinPoint 鍒囩偣
+     * @param e         寮傚父
+     */
+    @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")
+    public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) {
+        handleLog(joinPoint, controllerLog, e, null);
+    }
+
+    protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) {
+        try {
+
+            // *========鏁版嵁搴撴棩蹇�=========*//
+            OperLogEvent operLog = new OperLogEvent();
+            operLog.setTenantId(LoginHelper.getTenantId());
+            operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
+            // 璇锋眰鐨勫湴鍧�
+            String ip = ServletUtils.getClientIP();
+            operLog.setOperIp(ip);
+            operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255));
+            operLog.setOperName(LoginHelper.getUsername());
+
+            if (e != null) {
+                operLog.setStatus(BusinessStatus.FAIL.ordinal());
+                operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
+            }
+            // 璁剧疆鏂规硶鍚嶇О
+            String className = joinPoint.getTarget().getClass().getName();
+            String methodName = joinPoint.getSignature().getName();
+            operLog.setMethod(className + "." + methodName + "()");
+            // 璁剧疆璇锋眰鏂瑰紡
+            operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
+            // 澶勭悊璁剧疆娉ㄨВ涓婄殑鍙傛暟
+            getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
+            // 璁剧疆娑堣�楁椂闂�
+            StopWatch stopWatch = TIME_THREADLOCAL.get();
+            stopWatch.stop();
+            operLog.setCostTime(stopWatch.getTime());
+            // 鍙戝竷浜嬩欢淇濆瓨鏁版嵁搴�
+            SpringUtils.context().publishEvent(operLog);
+        } catch (Exception exp) {
+            // 璁板綍鏈湴寮傚父鏃ュ織
+            log.error("寮傚父淇℃伅:{}", exp.getMessage());
+            exp.printStackTrace();
+        } finally {
+            TIME_THREADLOCAL.remove();
+        }
+    }
+
+    /**
+     * 鑾峰彇娉ㄨВ涓鏂规硶鐨勬弿杩颁俊鎭� 鐢ㄤ簬Controller灞傛敞瑙�
+     *
+     * @param log     鏃ュ織
+     * @param operLog 鎿嶄綔鏃ュ織
+     * @throws Exception
+     */
+    public void getControllerMethodDescription(JoinPoint joinPoint, Log log, OperLogEvent operLog, Object jsonResult) throws Exception {
+        // 璁剧疆action鍔ㄤ綔
+        operLog.setBusinessType(log.businessType().ordinal());
+        // 璁剧疆鏍囬
+        operLog.setTitle(log.title());
+        // 璁剧疆鎿嶄綔浜虹被鍒�
+        operLog.setOperatorType(log.operatorType().ordinal());
+        // 鏄惁闇�瑕佷繚瀛榬equest锛屽弬鏁板拰鍊�
+        if (log.isSaveRequestData()) {
+            // 鑾峰彇鍙傛暟鐨勪俊鎭紝浼犲叆鍒版暟鎹簱涓��
+            setRequestValue(joinPoint, operLog, log.excludeParamNames());
+        }
+        // 鏄惁闇�瑕佷繚瀛榬esponse锛屽弬鏁板拰鍊�
+        if (log.isSaveResponseData() && ObjectUtil.isNotNull(jsonResult)) {
+            operLog.setJsonResult(StringUtils.substring(JsonUtils.toJsonString(jsonResult), 0, 2000));
+        }
+    }
+
+    /**
+     * 鑾峰彇璇锋眰鐨勫弬鏁帮紝鏀惧埌log涓�
+     *
+     * @param operLog 鎿嶄綔鏃ュ織
+     * @throws Exception 寮傚父
+     */
+    private void setRequestValue(JoinPoint joinPoint, OperLogEvent operLog, String[] excludeParamNames) throws Exception {
+        Map<String, String> paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest());
+        String requestMethod = operLog.getRequestMethod();
+        if (MapUtil.isEmpty(paramsMap)
+                && HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) {
+            String params = argsArrayToString(joinPoint.getArgs(), excludeParamNames);
+            operLog.setOperParam(StringUtils.substring(params, 0, 2000));
+        } else {
+            MapUtil.removeAny(paramsMap, EXCLUDE_PROPERTIES);
+            MapUtil.removeAny(paramsMap, excludeParamNames);
+            operLog.setOperParam(StringUtils.substring(JsonUtils.toJsonString(paramsMap), 0, 2000));
+        }
+    }
+
+    /**
+     * 鍙傛暟鎷艰
+     */
+    private String argsArrayToString(Object[] paramsArray, String[] excludeParamNames) {
+        StringBuilder params = new StringBuilder();
+        if (paramsArray != null && paramsArray.length > 0) {
+            for (Object o : paramsArray) {
+                if (ObjectUtil.isNotNull(o) && !isFilterObject(o)) {
+                    try {
+                        String str = JsonUtils.toJsonString(o);
+                        Dict dict = JsonUtils.parseMap(str);
+                        if (MapUtil.isNotEmpty(dict)) {
+                            MapUtil.removeAny(dict, EXCLUDE_PROPERTIES);
+                            MapUtil.removeAny(dict, excludeParamNames);
+                            str = JsonUtils.toJsonString(dict);
+                        }
+                        params.append(str).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-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/BusinessStatus.java b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/BusinessStatus.java
new file mode 100644
index 0000000..d303dc3
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/BusinessStatus.java
@@ -0,0 +1,18 @@
+package org.dromara.common.log.enums;
+
+/**
+ * 鎿嶄綔鐘舵��
+ *
+ * @author ruoyi
+ */
+public enum BusinessStatus {
+    /**
+     * 鎴愬姛
+     */
+    SUCCESS,
+
+    /**
+     * 澶辫触
+     */
+    FAIL,
+}
diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/BusinessType.java b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/BusinessType.java
new file mode 100644
index 0000000..2d25ebb
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/BusinessType.java
@@ -0,0 +1,58 @@
+package org.dromara.common.log.enums;
+
+/**
+ * 涓氬姟鎿嶄綔绫诲瀷
+ *
+ * @author ruoyi
+ */
+public enum BusinessType {
+    /**
+     * 鍏跺畠
+     */
+    OTHER,
+
+    /**
+     * 鏂板
+     */
+    INSERT,
+
+    /**
+     * 淇敼
+     */
+    UPDATE,
+
+    /**
+     * 鍒犻櫎
+     */
+    DELETE,
+
+    /**
+     * 鎺堟潈
+     */
+    GRANT,
+
+    /**
+     * 瀵煎嚭
+     */
+    EXPORT,
+
+    /**
+     * 瀵煎叆
+     */
+    IMPORT,
+
+    /**
+     * 寮洪��
+     */
+    FORCE,
+
+    /**
+     * 鐢熸垚浠g爜
+     */
+    GENCODE,
+
+    /**
+     * 娓呯┖鏁版嵁
+     */
+    CLEAN,
+}
diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/OperatorType.java b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/OperatorType.java
new file mode 100644
index 0000000..de9328b
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/OperatorType.java
@@ -0,0 +1,23 @@
+package org.dromara.common.log.enums;
+
+/**
+ * 鎿嶄綔浜虹被鍒�
+ *
+ * @author ruoyi
+ */
+public enum OperatorType {
+    /**
+     * 鍏跺畠
+     */
+    OTHER,
+
+    /**
+     * 鍚庡彴鐢ㄦ埛
+     */
+    MANAGE,
+
+    /**
+     * 鎵嬫満绔敤鎴�
+     */
+    MOBILE
+}
diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/LogininforEvent.java b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/LogininforEvent.java
new file mode 100644
index 0000000..938eaad
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/LogininforEvent.java
@@ -0,0 +1,52 @@
+package org.dromara.common.log.event;
+
+import lombok.Data;
+
+import jakarta.servlet.http.HttpServletRequest;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 鐧诲綍浜嬩欢
+ *
+ * @author Lion Li
+ */
+
+@Data
+public class LogininforEvent implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 绉熸埛ID
+     */
+    private String tenantId;
+
+    /**
+     * 鐢ㄦ埛璐﹀彿
+     */
+    private String username;
+
+    /**
+     * 鐧诲綍鐘舵�� 0鎴愬姛 1澶辫触
+     */
+    private String status;
+
+    /**
+     * 鎻愮ず娑堟伅
+     */
+    private String message;
+
+    /**
+     * 璇锋眰浣�
+     */
+    private HttpServletRequest request;
+
+    /**
+     * 鍏朵粬鍙傛暟
+     */
+    private Object[] args;
+
+}
diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/OperLogEvent.java b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/OperLogEvent.java
new file mode 100644
index 0000000..0386192
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/OperLogEvent.java
@@ -0,0 +1,115 @@
+package org.dromara.common.log.event;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 鎿嶄綔鏃ュ織浜嬩欢
+ *
+ * @author Lion Li
+ */
+
+@Data
+public class OperLogEvent implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鏃ュ織涓婚敭
+     */
+    private Long operId;
+
+    /**
+     * 绉熸埛ID
+     */
+    private String tenantId;
+
+    /**
+     * 鎿嶄綔妯″潡
+     */
+    private String title;
+
+    /**
+     * 涓氬姟绫诲瀷锛�0鍏跺畠 1鏂板 2淇敼 3鍒犻櫎锛�
+     */
+    private Integer businessType;
+
+    /**
+     * 涓氬姟绫诲瀷鏁扮粍
+     */
+    private Integer[] businessTypes;
+
+    /**
+     * 璇锋眰鏂规硶
+     */
+    private String method;
+
+    /**
+     * 璇锋眰鏂瑰紡
+     */
+    private String requestMethod;
+
+    /**
+     * 鎿嶄綔绫诲埆锛�0鍏跺畠 1鍚庡彴鐢ㄦ埛 2鎵嬫満绔敤鎴凤級
+     */
+    private Integer operatorType;
+
+    /**
+     * 鎿嶄綔浜哄憳
+     */
+    private String operName;
+
+    /**
+     * 閮ㄩ棬鍚嶇О
+     */
+    private String deptName;
+
+    /**
+     * 璇锋眰url
+     */
+    private String operUrl;
+
+    /**
+     * 鎿嶄綔鍦板潃
+     */
+    private String operIp;
+
+    /**
+     * 鎿嶄綔鍦扮偣
+     */
+    private String operLocation;
+
+    /**
+     * 璇锋眰鍙傛暟
+     */
+    private String operParam;
+
+    /**
+     * 杩斿洖鍙傛暟
+     */
+    private String jsonResult;
+
+    /**
+     * 鎿嶄綔鐘舵�侊紙0姝e父 1寮傚父锛�
+     */
+    private Integer status;
+
+    /**
+     * 閿欒娑堟伅
+     */
+    private String errorMsg;
+
+    /**
+     * 鎿嶄綔鏃堕棿
+     */
+    private Date operTime;
+
+    /**
+     * 娑堣�楁椂闂�
+     */
+    private Long costTime;
+}
diff --git a/ruoyi-common/ruoyi-common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index b8e3223..6893020 100644
--- a/ruoyi-common/ruoyi-common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-common/ruoyi-common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +1 @@
-com.ruoyi.common.log.aspect.LogAspect
+org.dromara.common.log.aspect.LogAspect
diff --git a/ruoyi-common/ruoyi-common-mail/pom.xml b/ruoyi-common/ruoyi-common-mail/pom.xml
index 17d80d8..6a16e80 100644
--- a/ruoyi-common/ruoyi-common-mail/pom.xml
+++ b/ruoyi-common/ruoyi-common-mail/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-common</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -18,7 +18,7 @@
 
     <dependencies>
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-core</artifactId>
         </dependency>
 
diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/com/ruoyi/common/mail/config/MailConfig.java b/ruoyi-common/ruoyi-common-mail/src/main/java/com/ruoyi/common/mail/config/MailConfig.java
deleted file mode 100644
index 7ad8bce..0000000
--- a/ruoyi-common/ruoyi-common-mail/src/main/java/com/ruoyi/common/mail/config/MailConfig.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.ruoyi.common.mail.config;
-
-import cn.hutool.extra.mail.MailAccount;
-import com.ruoyi.common.mail.config.properties.MailProperties;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-
-/**
- * JavaMail 閰嶇疆
- *
- * @author Michelle.Chung
- */
-@AutoConfiguration
-@EnableConfigurationProperties(MailProperties.class)
-public class MailConfig {
-
-    @Bean
-    @ConditionalOnProperty(value = "mail.enabled", havingValue = "true")
-    public MailAccount mailAccount(MailProperties mailProperties) {
-        MailAccount account = new MailAccount();
-        account.setHost(mailProperties.getHost());
-        account.setPort(mailProperties.getPort());
-        account.setAuth(mailProperties.getAuth());
-        account.setFrom(mailProperties.getFrom());
-        account.setUser(mailProperties.getUser());
-        account.setPass(mailProperties.getPass());
-        account.setSocketFactoryPort(mailProperties.getPort());
-        account.setStarttlsEnable(mailProperties.getStarttlsEnable());
-        account.setSslEnable(mailProperties.getSslEnable());
-        account.setTimeout(mailProperties.getTimeout());
-        account.setConnectionTimeout(mailProperties.getConnectionTimeout());
-        return account;
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/com/ruoyi/common/mail/config/properties/MailProperties.java b/ruoyi-common/ruoyi-common-mail/src/main/java/com/ruoyi/common/mail/config/properties/MailProperties.java
deleted file mode 100644
index 7970e47..0000000
--- a/ruoyi-common/ruoyi-common-mail/src/main/java/com/ruoyi/common/mail/config/properties/MailProperties.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package com.ruoyi.common.mail.config.properties;
-
-import lombok.Data;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-/**
- * JavaMail 閰嶇疆灞炴��
- *
- * @author Michelle.Chung
- */
-@Data
-@ConfigurationProperties(prefix = "mail")
-public class MailProperties {
-
-    /**
-     * 杩囨护寮�鍏�
-     */
-    private Boolean enabled;
-
-    /**
-     * SMTP鏈嶅姟鍣ㄥ煙鍚�
-     */
-    private String host;
-
-    /**
-     * SMTP鏈嶅姟绔彛
-     */
-    private Integer port;
-
-    /**
-     * 鏄惁闇�瑕佺敤鎴峰悕瀵嗙爜楠岃瘉
-     */
-    private Boolean auth;
-
-    /**
-     * 鐢ㄦ埛鍚�
-     */
-    private String user;
-
-    /**
-     * 瀵嗙爜
-     */
-    private String pass;
-
-    /**
-     * 鍙戦�佹柟锛岄伒寰猂FC-822鏍囧噯
-     */
-    private String from;
-
-    /**
-     * 浣跨敤 STARTTLS瀹夊叏杩炴帴锛孲TARTTLS鏄绾枃鏈�氫俊鍗忚鐨勬墿灞曘�傚畠灏嗙函鏂囨湰杩炴帴鍗囩骇涓哄姞瀵嗚繛鎺ワ紙TLS鎴朣SL锛夛紝 鑰屼笉鏄娇鐢ㄤ竴涓崟鐙殑鍔犲瘑閫氫俊绔彛銆�
-     */
-    private Boolean starttlsEnable;
-
-    /**
-     * 浣跨敤 SSL瀹夊叏杩炴帴
-     */
-    private Boolean sslEnable;
-
-    /**
-     * SMTP瓒呮椂鏃堕暱锛屽崟浣嶆绉掞紝缂虹渷鍊间笉瓒呮椂
-     */
-    private Long timeout;
-
-    /**
-     * Socket杩炴帴瓒呮椂鍊硷紝鍗曚綅姣锛岀己鐪佸�间笉瓒呮椂
-     */
-    private Long connectionTimeout;
-}
diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/com/ruoyi/common/mail/utils/InternalMailUtil.java b/ruoyi-common/ruoyi-common-mail/src/main/java/com/ruoyi/common/mail/utils/InternalMailUtil.java
deleted file mode 100644
index 28543c0..0000000
--- a/ruoyi-common/ruoyi-common-mail/src/main/java/com/ruoyi/common/mail/utils/InternalMailUtil.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package com.ruoyi.common.mail.utils;
-
-import cn.hutool.core.util.ArrayUtil;
-import cn.hutool.extra.mail.MailException;
-import jakarta.mail.internet.AddressException;
-import jakarta.mail.internet.InternetAddress;
-import jakarta.mail.internet.MimeUtility;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * 閭欢鍐呴儴宸ュ叿绫�
- * @author looly
- * @since 3.2.3
- */
-public class InternalMailUtil {
-
-	/**
-	 * 灏嗗涓瓧绗︿覆閭欢鍦板潃杞负{@link InternetAddress}鍒楄〃<br>
-	 * 鍗曚釜瀛楃涓插湴鍧�鍙互鏄涓湴鍧�鍚堝苟鐨勫瓧绗︿覆
-	 *
-	 * @param addrStrs 鍦板潃鏁扮粍
-	 * @param charset 缂栫爜锛堜富瑕佺敤浜庝腑鏂囩敤鎴峰悕鐨勭紪鐮侊級
-	 * @return 鍦板潃鏁扮粍
-	 * @since 4.0.3
-	 */
-	public static InternetAddress[] parseAddressFromStrs(String[] addrStrs, Charset charset) {
-		final List<InternetAddress> resultList = new ArrayList<>(addrStrs.length);
-		InternetAddress[] addrs;
-		for (String addrStr : addrStrs) {
-			addrs = parseAddress(addrStr, charset);
-			if (ArrayUtil.isNotEmpty(addrs)) {
-				Collections.addAll(resultList, addrs);
-			}
-		}
-		return resultList.toArray(new InternetAddress[0]);
-	}
-
-	/**
-	 * 瑙f瀽绗竴涓湴鍧�
-	 *
-	 * @param address 鍦板潃瀛楃涓�
-	 * @param charset 缂栫爜锛寋@code null}琛ㄧず浣跨敤绯荤粺灞炴�у畾涔夌殑缂栫爜鎴栫郴缁熺紪鐮�
-	 * @return 鍦板潃鍒楄〃
-	 */
-	public static InternetAddress parseFirstAddress(String address, Charset charset) {
-		final InternetAddress[] internetAddresses = parseAddress(address, charset);
-		if (ArrayUtil.isEmpty(internetAddresses)) {
-			try {
-				return new InternetAddress(address);
-			} catch (AddressException e) {
-				throw new MailException(e);
-			}
-		}
-		return internetAddresses[0];
-	}
-
-	/**
-	 * 灏嗕竴涓湴鍧�瀛楃涓茶В鏋愪负澶氫釜鍦板潃<br>
-	 * 鍦板潃闂翠娇鐢�" "銆�","銆�";"鍒嗛殧
-	 *
-	 * @param address 鍦板潃瀛楃涓�
-	 * @param charset 缂栫爜锛寋@code null}琛ㄧず浣跨敤绯荤粺灞炴�у畾涔夌殑缂栫爜鎴栫郴缁熺紪鐮�
-	 * @return 鍦板潃鍒楄〃
-	 */
-	public static InternetAddress[] parseAddress(String address, Charset charset) {
-		InternetAddress[] addresses;
-		try {
-			addresses = InternetAddress.parse(address);
-		} catch (AddressException e) {
-			throw new MailException(e);
-		}
-		//缂栫爜鐢ㄦ埛鍚�
-		if (ArrayUtil.isNotEmpty(addresses)) {
-			final String charsetStr = null == charset ? null : charset.name();
-			for (InternetAddress internetAddress : addresses) {
-				try {
-					internetAddress.setPersonal(internetAddress.getPersonal(), charsetStr);
-				} catch (UnsupportedEncodingException e) {
-					throw new MailException(e);
-				}
-			}
-		}
-
-		return addresses;
-	}
-
-	/**
-	 * 缂栫爜涓枃瀛楃<br>
-	 * 缂栫爜澶辫触杩斿洖鍘熷瓧绗︿覆
-	 *
-	 * @param text 琚紪鐮佺殑鏂囨湰
-	 * @param charset 缂栫爜
-	 * @return 缂栫爜鍚庣殑缁撴灉
-	 */
-	public static String encodeText(String text, Charset charset) {
-		try {
-			return MimeUtility.encodeText(text, charset.name(), null);
-		} catch (UnsupportedEncodingException e) {
-			// ignore
-		}
-		return text;
-	}
-}
diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/com/ruoyi/common/mail/utils/Mail.java b/ruoyi-common/ruoyi-common-mail/src/main/java/com/ruoyi/common/mail/utils/Mail.java
deleted file mode 100644
index 5599be3..0000000
--- a/ruoyi-common/ruoyi-common-mail/src/main/java/com/ruoyi/common/mail/utils/Mail.java
+++ /dev/null
@@ -1,486 +0,0 @@
-package com.ruoyi.common.mail.utils;
-
-import cn.hutool.core.builder.Builder;
-import cn.hutool.core.io.FileUtil;
-import cn.hutool.core.io.IORuntimeException;
-import cn.hutool.core.io.IoUtil;
-import cn.hutool.core.util.ArrayUtil;
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.extra.mail.*;
-import jakarta.activation.DataHandler;
-import jakarta.activation.DataSource;
-import jakarta.activation.FileDataSource;
-import jakarta.activation.FileTypeMap;
-import jakarta.mail.*;
-import jakarta.mail.internet.MimeBodyPart;
-import jakarta.mail.internet.MimeMessage;
-import jakarta.mail.internet.MimeMultipart;
-import jakarta.mail.internet.MimeUtility;
-import jakarta.mail.util.ByteArrayDataSource;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.nio.charset.Charset;
-import java.util.Date;
-
-/**
- * 閭欢鍙戦�佸鎴风
- *
- * @author looly
- * @since 3.2.0
- */
-public class Mail implements Builder<MimeMessage> {
-	private static final long serialVersionUID = 1L;
-
-	/**
-	 * 閭甯愭埛淇℃伅浠ュ強涓�浜涘鎴风閰嶇疆淇℃伅
-	 */
-	private final MailAccount mailAccount;
-	/**
-	 * 鏀朵欢浜哄垪琛�
-	 */
-	private String[] tos;
-	/**
-	 * 鎶勯�佷汉鍒楄〃锛坈arbon copy锛�
-	 */
-	private String[] ccs;
-	/**
-	 * 瀵嗛�佷汉鍒楄〃锛坆lind carbon copy锛�
-	 */
-	private String[] bccs;
-	/**
-	 * 鍥炲鍦板潃(reply-to)
-	 */
-	private String[] reply;
-	/**
-	 * 鏍囬
-	 */
-	private String title;
-	/**
-	 * 鍐呭
-	 */
-	private String content;
-	/**
-	 * 鏄惁涓篐TML
-	 */
-	private boolean isHtml;
-	/**
-	 * 姝f枃銆侀檮浠跺拰鍥剧墖鐨勬贩鍚堥儴鍒�
-	 */
-	private final Multipart multipart = new MimeMultipart();
-	/**
-	 * 鏄惁浣跨敤鍏ㄥ眬浼氳瘽锛岄粯璁や负false
-	 */
-	private boolean useGlobalSession = false;
-
-	/**
-	 * debug杈撳嚭浣嶇疆锛屽彲浠ヨ嚜瀹氫箟debug鏃ュ織
-	 */
-	private PrintStream debugOutput;
-
-	/**
-	 * 鍒涘缓閭欢瀹㈡埛绔�
-	 *
-	 * @param mailAccount 閭欢甯愬彿
-	 * @return Mail
-	 */
-	public static Mail create(MailAccount mailAccount) {
-		return new Mail(mailAccount);
-	}
-
-	/**
-	 * 鍒涘缓閭欢瀹㈡埛绔紝浣跨敤鍏ㄥ眬閭欢甯愭埛
-	 *
-	 * @return Mail
-	 */
-	public static Mail create() {
-		return new Mail();
-	}
-
-	// --------------------------------------------------------------- Constructor start
-
-	/**
-	 * 鏋勯�狅紝浣跨敤鍏ㄥ眬閭欢甯愭埛
-	 */
-	public Mail() {
-		this(GlobalMailAccount.INSTANCE.getAccount());
-	}
-
-	/**
-	 * 鏋勯��
-	 *
-	 * @param mailAccount 閭欢甯愭埛锛屽鏋滀负null浣跨敤榛樿閰嶇疆鏂囦欢鐨勫叏灞�閭欢閰嶇疆
-	 */
-	public Mail(MailAccount mailAccount) {
-		mailAccount = (null != mailAccount) ? mailAccount : GlobalMailAccount.INSTANCE.getAccount();
-		this.mailAccount = mailAccount.defaultIfEmpty();
-	}
-	// --------------------------------------------------------------- Constructor end
-
-	// --------------------------------------------------------------- Getters and Setters start
-
-	/**
-	 * 璁剧疆鏀朵欢浜�
-	 *
-	 * @param tos 鏀朵欢浜哄垪琛�
-	 * @return this
-	 * @see #setTos(String...)
-	 */
-	public Mail to(String... tos) {
-		return setTos(tos);
-	}
-
-	/**
-	 * 璁剧疆澶氫釜鏀朵欢浜�
-	 *
-	 * @param tos 鏀朵欢浜哄垪琛�
-	 * @return this
-	 */
-	public Mail setTos(String... tos) {
-		this.tos = tos;
-		return this;
-	}
-
-	/**
-	 * 璁剧疆澶氫釜鎶勯�佷汉锛坈arbon copy锛�
-	 *
-	 * @param ccs 鎶勯�佷汉鍒楄〃
-	 * @return this
-	 * @since 4.0.3
-	 */
-	public Mail setCcs(String... ccs) {
-		this.ccs = ccs;
-		return this;
-	}
-
-	/**
-	 * 璁剧疆澶氫釜瀵嗛�佷汉锛坆lind carbon copy锛�
-	 *
-	 * @param bccs 瀵嗛�佷汉鍒楄〃
-	 * @return this
-	 * @since 4.0.3
-	 */
-	public Mail setBccs(String... bccs) {
-		this.bccs = bccs;
-		return this;
-	}
-
-	/**
-	 * 璁剧疆澶氫釜鍥炲鍦板潃(reply-to)
-	 *
-	 * @param reply 鍥炲鍦板潃(reply-to)鍒楄〃
-	 * @return this
-	 * @since 4.6.0
-	 */
-	public Mail setReply(String... reply) {
-		this.reply = reply;
-		return this;
-	}
-
-	/**
-	 * 璁剧疆鏍囬
-	 *
-	 * @param title 鏍囬
-	 * @return this
-	 */
-	public Mail setTitle(String title) {
-		this.title = title;
-		return this;
-	}
-
-	/**
-	 * 璁剧疆姝f枃<br>
-	 * 姝f枃鍙互鏄櫘閫氭枃鏈篃鍙互鏄疕TML锛堥粯璁ゆ櫘閫氭枃鏈級锛屽彲浠ラ�氳繃璋冪敤{@link #setHtml(boolean)} 璁剧疆鏄惁涓篐TML
-	 *
-	 * @param content 姝f枃
-	 * @return this
-	 */
-	public Mail setContent(String content) {
-		this.content = content;
-		return this;
-	}
-
-	/**
-	 * 璁剧疆鏄惁鏄疕TML
-	 *
-	 * @param isHtml 鏄惁涓篐TML
-	 * @return this
-	 */
-	public Mail setHtml(boolean isHtml) {
-		this.isHtml = isHtml;
-		return this;
-	}
-
-	/**
-	 * 璁剧疆姝f枃
-	 *
-	 * @param content 姝f枃鍐呭
-	 * @param isHtml  鏄惁涓篐TML
-	 * @return this
-	 */
-	public Mail setContent(String content, boolean isHtml) {
-		setContent(content);
-		return setHtml(isHtml);
-	}
-
-	/**
-	 * 璁剧疆鏂囦欢绫诲瀷闄勪欢锛屾枃浠跺彲浠ユ槸鍥剧墖鏂囦欢锛屾鏃惰嚜鍔ㄨ缃甤id锛堟鏂囦腑寮曠敤鍥剧墖锛夛紝榛樿cid涓烘枃浠跺悕
-	 *
-	 * @param files 闄勪欢鏂囦欢鍒楄〃
-	 * @return this
-	 */
-	public Mail setFiles(File... files) {
-		if (ArrayUtil.isEmpty(files)) {
-			return this;
-		}
-
-		final DataSource[] attachments = new DataSource[files.length];
-		for (int i = 0; i < files.length; i++) {
-			attachments[i] = new FileDataSource(files[i]);
-		}
-		return setAttachments(attachments);
-	}
-
-	/**
-	 * 澧炲姞闄勪欢鎴栧浘鐗囷紝闄勪欢浣跨敤{@link DataSource} 褰㈠紡琛ㄧず锛屽彲浠ヤ娇鐢▄@link FileDataSource}鍖呰鏂囦欢琛ㄧず鏂囦欢闄勪欢
-	 *
-	 * @param attachments 闄勪欢鍒楄〃
-	 * @return this
-	 * @since 4.0.9
-	 */
-	public Mail setAttachments(DataSource... attachments) {
-		if (ArrayUtil.isNotEmpty(attachments)) {
-			final Charset charset = this.mailAccount.getCharset();
-			MimeBodyPart bodyPart;
-			String nameEncoded;
-			try {
-				for (DataSource attachment : attachments) {
-					bodyPart = new MimeBodyPart();
-					bodyPart.setDataHandler(new DataHandler(attachment));
-					nameEncoded = attachment.getName();
-					if (this.mailAccount.isEncodefilename()) {
-						nameEncoded = InternalMailUtil.encodeText(nameEncoded, charset);
-					}
-					// 鏅�氶檮浠舵枃浠跺悕
-					bodyPart.setFileName(nameEncoded);
-					if (StrUtil.startWith(attachment.getContentType(), "image/")) {
-						// 鍥剧墖闄勪欢锛岀敤浜庢鏂囦腑寮曠敤鍥剧墖
-						bodyPart.setContentID(nameEncoded);
-					}
-					this.multipart.addBodyPart(bodyPart);
-				}
-			} catch (MessagingException e) {
-				throw new MailException(e);
-			}
-		}
-		return this;
-	}
-
-	/**
-	 * 澧炲姞鍥剧墖锛屽浘鐗囩殑閿搴斿埌閭欢妯℃澘涓殑鍗犱綅瀛楃涓诧紝鍥剧墖绫诲瀷榛樿涓�"image/jpeg"
-	 *
-	 * @param cid         鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:${cid}
-	 * @param imageStream 鍥剧墖鏂囦欢
-	 * @return this
-	 * @since 4.6.3
-	 */
-	public Mail addImage(String cid, InputStream imageStream) {
-		return addImage(cid, imageStream, null);
-	}
-
-	/**
-	 * 澧炲姞鍥剧墖锛屽浘鐗囩殑閿搴斿埌閭欢妯℃澘涓殑鍗犱綅瀛楃涓�
-	 *
-	 * @param cid         鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:${cid}
-	 * @param imageStream 鍥剧墖娴侊紝涓嶅叧闂�
-	 * @param contentType 鍥剧墖绫诲瀷锛宯ull璧嬪�奸粯璁ょ殑"image/jpeg"
-	 * @return this
-	 * @since 4.6.3
-	 */
-	public Mail addImage(String cid, InputStream imageStream, String contentType) {
-		ByteArrayDataSource imgSource;
-		try {
-			imgSource = new ByteArrayDataSource(imageStream, ObjectUtil.defaultIfNull(contentType, "image/jpeg"));
-		} catch (IOException e) {
-			throw new IORuntimeException(e);
-		}
-		imgSource.setName(cid);
-		return setAttachments(imgSource);
-	}
-
-	/**
-	 * 澧炲姞鍥剧墖锛屽浘鐗囩殑閿搴斿埌閭欢妯℃澘涓殑鍗犱綅瀛楃涓�
-	 *
-	 * @param cid       鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:${cid}
-	 * @param imageFile 鍥剧墖鏂囦欢
-	 * @return this
-	 * @since 4.6.3
-	 */
-	public Mail addImage(String cid, File imageFile) {
-		InputStream in = null;
-		try {
-			in = FileUtil.getInputStream(imageFile);
-			return addImage(cid, in, FileTypeMap.getDefaultFileTypeMap().getContentType(imageFile));
-		} finally {
-			IoUtil.close(in);
-		}
-	}
-
-	/**
-	 * 璁剧疆瀛楃闆嗙紪鐮�
-	 *
-	 * @param charset 瀛楃闆嗙紪鐮�
-	 * @return this
-	 * @see MailAccount#setCharset(Charset)
-	 */
-	public Mail setCharset(Charset charset) {
-		this.mailAccount.setCharset(charset);
-		return this;
-	}
-
-	/**
-	 * 璁剧疆鏄惁浣跨敤鍏ㄥ眬浼氳瘽锛岄粯璁や负true
-	 *
-	 * @param isUseGlobalSession 鏄惁浣跨敤鍏ㄥ眬浼氳瘽锛岄粯璁や负true
-	 * @return this
-	 * @since 4.0.2
-	 */
-	public Mail setUseGlobalSession(boolean isUseGlobalSession) {
-		this.useGlobalSession = isUseGlobalSession;
-		return this;
-	}
-
-	/**
-	 * 璁剧疆debug杈撳嚭浣嶇疆锛屽彲浠ヨ嚜瀹氫箟debug鏃ュ織
-	 *
-	 * @param debugOutput debug杈撳嚭浣嶇疆
-	 * @return this
-	 * @since 5.5.6
-	 */
-	public Mail setDebugOutput(PrintStream debugOutput) {
-		this.debugOutput = debugOutput;
-		return this;
-	}
-	// --------------------------------------------------------------- Getters and Setters end
-
-	@Override
-	public MimeMessage build() {
-		try {
-			return buildMsg();
-		} catch (MessagingException e) {
-			throw new MailException(e);
-		}
-	}
-
-	/**
-	 * 鍙戦��
-	 *
-	 * @return message-id
-	 * @throws MailException 閭欢鍙戦�佸紓甯�
-	 */
-	public String send() throws MailException {
-		try {
-			return doSend();
-		} catch (MessagingException e) {
-			if (e instanceof SendFailedException) {
-				// 褰撳湴鍧�鏃犳晥鏃讹紝鏄剧ず鏇村姞璇︾粏鐨勬棤鏁堝湴鍧�淇℃伅
-				final Address[] invalidAddresses = ((SendFailedException) e).getInvalidAddresses();
-				final String msg = StrUtil.format("Invalid Addresses: {}", ArrayUtil.toString(invalidAddresses));
-				throw new MailException(msg, e);
-			}
-			throw new MailException(e);
-		}
-	}
-
-	// --------------------------------------------------------------- Private method start
-
-	/**
-	 * 鎵ц鍙戦��
-	 *
-	 * @return message-id
-	 * @throws MessagingException 鍙戦�佸紓甯�
-	 */
-	private String doSend() throws MessagingException {
-		final MimeMessage mimeMessage = buildMsg();
-		Transport.send(mimeMessage);
-		return mimeMessage.getMessageID();
-	}
-
-	/**
-	 * 鏋勫缓娑堟伅
-	 *
-	 * @return {@link MimeMessage}娑堟伅
-	 * @throws MessagingException 娑堟伅寮傚父
-	 */
-	private MimeMessage buildMsg() throws MessagingException {
-		final Charset charset = this.mailAccount.getCharset();
-		final MimeMessage msg = new MimeMessage(getSession());
-		// 鍙戜欢浜�
-		final String from = this.mailAccount.getFrom();
-		if (StrUtil.isEmpty(from)) {
-			// 鐢ㄦ埛鏈彁渚涘彂閫佹柟锛屽垯浠嶴ession涓嚜鍔ㄨ幏鍙�
-			msg.setFrom();
-		} else {
-			msg.setFrom(InternalMailUtil.parseFirstAddress(from, charset));
-		}
-		// 鏍囬
-		msg.setSubject(this.title, (null == charset) ? null : charset.name());
-		// 鍙戦�佹椂闂�
-		msg.setSentDate(new Date());
-		// 鍐呭鍜岄檮浠�
-		msg.setContent(buildContent(charset));
-		// 鏀朵欢浜�
-		msg.setRecipients(MimeMessage.RecipientType.TO, InternalMailUtil.parseAddressFromStrs(this.tos, charset));
-		// 鎶勯�佷汉
-		if (ArrayUtil.isNotEmpty(this.ccs)) {
-			msg.setRecipients(MimeMessage.RecipientType.CC, InternalMailUtil.parseAddressFromStrs(this.ccs, charset));
-		}
-		// 瀵嗛�佷汉
-		if (ArrayUtil.isNotEmpty(this.bccs)) {
-			msg.setRecipients(MimeMessage.RecipientType.BCC, InternalMailUtil.parseAddressFromStrs(this.bccs, charset));
-		}
-		// 鍥炲鍦板潃(reply-to)
-		if (ArrayUtil.isNotEmpty(this.reply)) {
-			msg.setReplyTo(InternalMailUtil.parseAddressFromStrs(this.reply, charset));
-		}
-
-		return msg;
-	}
-
-	/**
-	 * 鏋勫缓閭欢淇℃伅涓讳綋
-	 *
-	 * @param charset 缂栫爜锛寋@code null}鍒欎娇鐢▄@link MimeUtility#getDefaultJavaCharset()}
-	 * @return 閭欢淇℃伅涓讳綋
-	 * @throws MessagingException 娑堟伅寮傚父
-	 */
-	private Multipart buildContent(Charset charset) throws MessagingException {
-		final String charsetStr = null != charset ? charset.name() : MimeUtility.getDefaultJavaCharset();
-		// 姝f枃
-		final MimeBodyPart body = new MimeBodyPart();
-		body.setContent(content, StrUtil.format("text/{}; charset={}", isHtml ? "html" : "plain", charsetStr));
-		this.multipart.addBodyPart(body);
-
-		return this.multipart;
-	}
-
-	/**
-	 * 鑾峰彇榛樿閭欢浼氳瘽<br>
-	 * 濡傛灉涓哄叏灞�鍗曚緥鐨勪細璇濓紝鍒欏叏灞�鍙厑璁镐竴涓偖浠跺笎鍙凤紝鍚﹀垯姣忔鍙戦�侀偖浠朵細鏂板缓涓�涓柊鐨勪細璇�
-	 *
-	 * @return 閭欢浼氳瘽 {@link Session}
-	 */
-	private Session getSession() {
-		final Session session = MailUtils.getSession(this.mailAccount, this.useGlobalSession);
-
-		if (null != this.debugOutput) {
-			session.setDebugOut(debugOutput);
-		}
-
-		return session;
-	}
-	// --------------------------------------------------------------- Private method end
-}
diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/com/ruoyi/common/mail/utils/MailUtils.java b/ruoyi-common/ruoyi-common-mail/src/main/java/com/ruoyi/common/mail/utils/MailUtils.java
deleted file mode 100644
index 81f2834..0000000
--- a/ruoyi-common/ruoyi-common-mail/src/main/java/com/ruoyi/common/mail/utils/MailUtils.java
+++ /dev/null
@@ -1,468 +0,0 @@
-package com.ruoyi.common.mail.utils;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.io.IoUtil;
-import cn.hutool.core.map.MapUtil;
-import cn.hutool.core.util.CharUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.extra.mail.*;
-import com.ruoyi.common.core.utils.SpringUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-
-import jakarta.mail.Authenticator;
-import jakarta.mail.Session;
-import java.io.File;
-import java.io.InputStream;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-
-/**
- * 閭欢宸ュ叿绫�
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class MailUtils {
-
-    private static final MailAccount ACCOUNT = SpringUtils.getBean(MailAccount.class);
-
-    /**
-     * 鑾峰彇閭欢鍙戦�佸疄渚�
-     */
-    public static MailAccount getMailAccount() {
-        return ACCOUNT;
-    }
-
-    /**
-     * 鑾峰彇閭欢鍙戦�佸疄渚� (鑷畾涔夊彂閫佷汉浠ュ強鎺堟潈鐮�)
-     *
-     * @param user 鍙戦�佷汉
-     * @param pass 鎺堟潈鐮�
-     */
-    public static MailAccount getMailAccount(String from, String user, String pass) {
-        ACCOUNT.setFrom(StringUtils.blankToDefault(from, ACCOUNT.getFrom()));
-        ACCOUNT.setUser(StringUtils.blankToDefault(user, ACCOUNT.getUser()));
-        ACCOUNT.setPass(StringUtils.blankToDefault(pass, ACCOUNT.getPass()));
-        return ACCOUNT;
-    }
-
-    /**
-     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�佹枃鏈偖浠讹紝鍙戦�佺粰鍗曚釜鎴栧涓敹浠朵汉<br>
-     * 澶氫釜鏀朵欢浜哄彲浠ヤ娇鐢ㄩ�楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
-     *
-     * @param to      鏀朵欢浜�
-     * @param subject 鏍囬
-     * @param content 姝f枃
-     * @param files   闄勪欢鍒楄〃
-     * @return message-id
-     * @since 3.2.0
-     */
-    public static String sendText(String to, String subject, String content, File... files) {
-        return send(to, subject, content, false, files);
-    }
-
-    /**
-     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�丠TML閭欢锛屽彂閫佺粰鍗曚釜鎴栧涓敹浠朵汉<br>
-     * 澶氫釜鏀朵欢浜哄彲浠ヤ娇鐢ㄩ�楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
-     *
-     * @param to      鏀朵欢浜�
-     * @param subject 鏍囬
-     * @param content 姝f枃
-     * @param files   闄勪欢鍒楄〃
-     * @return message-id
-     * @since 3.2.0
-     */
-    public static String sendHtml(String to, String subject, String content, File... files) {
-        return send(to, subject, content, true, files);
-    }
-
-    /**
-     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�侀偖浠讹紝鍙戦�佸崟涓垨澶氫釜鏀朵欢浜�<br>
-     * 澶氫釜鏀朵欢浜哄彲浠ヤ娇鐢ㄩ�楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
-     *
-     * @param to      鏀朵欢浜�
-     * @param subject 鏍囬
-     * @param content 姝f枃
-     * @param isHtml  鏄惁涓篐TML
-     * @param files   闄勪欢鍒楄〃
-     * @return message-id
-     */
-    public static String send(String to, String subject, String content, boolean isHtml, File... files) {
-        return send(splitAddress(to), subject, content, isHtml, files);
-    }
-
-    /**
-     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�侀偖浠讹紝鍙戦�佸崟涓垨澶氫釜鏀朵欢浜�<br>
-     * 澶氫釜鏀朵欢浜恒�佹妱閫佷汉銆佸瘑閫佷汉鍙互浣跨敤閫楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
-     *
-     * @param to      鏀朵欢浜猴紝鍙互浣跨敤閫楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
-     * @param cc      鎶勯�佷汉锛屽彲浠ヤ娇鐢ㄩ�楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
-     * @param bcc     瀵嗛�佷汉锛屽彲浠ヤ娇鐢ㄩ�楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
-     * @param subject 鏍囬
-     * @param content 姝f枃
-     * @param isHtml  鏄惁涓篐TML
-     * @param files   闄勪欢鍒楄〃
-     * @return message-id
-     * @since 4.0.3
-     */
-    public static String send(String to, String cc, String bcc, String subject, String content, boolean isHtml, File... files) {
-        return send(splitAddress(to), splitAddress(cc), splitAddress(bcc), subject, content, isHtml, files);
-    }
-
-    /**
-     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�佹枃鏈偖浠讹紝鍙戦�佺粰澶氫汉
-     *
-     * @param tos     鏀朵欢浜哄垪琛�
-     * @param subject 鏍囬
-     * @param content 姝f枃
-     * @param files   闄勪欢鍒楄〃
-     * @return message-id
-     */
-    public static String sendText(Collection<String> tos, String subject, String content, File... files) {
-        return send(tos, subject, content, false, files);
-    }
-
-    /**
-     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�丠TML閭欢锛屽彂閫佺粰澶氫汉
-     *
-     * @param tos     鏀朵欢浜哄垪琛�
-     * @param subject 鏍囬
-     * @param content 姝f枃
-     * @param files   闄勪欢鍒楄〃
-     * @return message-id
-     * @since 3.2.0
-     */
-    public static String sendHtml(Collection<String> tos, String subject, String content, File... files) {
-        return send(tos, subject, content, true, files);
-    }
-
-    /**
-     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�侀偖浠讹紝鍙戦�佺粰澶氫汉
-     *
-     * @param tos     鏀朵欢浜哄垪琛�
-     * @param subject 鏍囬
-     * @param content 姝f枃
-     * @param isHtml  鏄惁涓篐TML
-     * @param files   闄勪欢鍒楄〃
-     * @return message-id
-     */
-    public static String send(Collection<String> tos, String subject, String content, boolean isHtml, File... files) {
-        return send(tos, null, null, subject, content, isHtml, files);
-    }
-
-    /**
-     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�侀偖浠讹紝鍙戦�佺粰澶氫汉
-     *
-     * @param tos     鏀朵欢浜哄垪琛�
-     * @param ccs     鎶勯�佷汉鍒楄〃锛屽彲浠ヤ负null鎴栫┖
-     * @param bccs    瀵嗛�佷汉鍒楄〃锛屽彲浠ヤ负null鎴栫┖
-     * @param subject 鏍囬
-     * @param content 姝f枃
-     * @param isHtml  鏄惁涓篐TML
-     * @param files   闄勪欢鍒楄〃
-     * @return message-id
-     * @since 4.0.3
-     */
-    public static String send(Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content, boolean isHtml, File... files) {
-        return send(getMailAccount(), true, tos, ccs, bccs, subject, content, null, isHtml, files);
-    }
-
-    // ------------------------------------------------------------------------------------------------------------------------------- Custom MailAccount
-
-    /**
-     * 鍙戦�侀偖浠剁粰澶氫汉
-     *
-     * @param mailAccount 閭欢璁よ瘉瀵硅薄
-     * @param to          鏀朵欢浜猴紝澶氫釜鏀朵欢浜洪�楀彿鎴栬�呭垎鍙烽殧寮�
-     * @param subject     鏍囬
-     * @param content     姝f枃
-     * @param isHtml      鏄惁涓篐TML鏍煎紡
-     * @param files       闄勪欢鍒楄〃
-     * @return message-id
-     * @since 3.2.0
-     */
-    public static String send(MailAccount mailAccount, String to, String subject, String content, boolean isHtml, File... files) {
-        return send(mailAccount, splitAddress(to), subject, content, isHtml, files);
-    }
-
-    /**
-     * 鍙戦�侀偖浠剁粰澶氫汉
-     *
-     * @param mailAccount 閭欢甯愭埛淇℃伅
-     * @param tos         鏀朵欢浜哄垪琛�
-     * @param subject     鏍囬
-     * @param content     姝f枃
-     * @param isHtml      鏄惁涓篐TML鏍煎紡
-     * @param files       闄勪欢鍒楄〃
-     * @return message-id
-     */
-    public static String send(MailAccount mailAccount, Collection<String> tos, String subject, String content, boolean isHtml, File... files) {
-        return send(mailAccount, tos, null, null, subject, content, isHtml, files);
-    }
-
-    /**
-     * 鍙戦�侀偖浠剁粰澶氫汉
-     *
-     * @param mailAccount 閭欢甯愭埛淇℃伅
-     * @param tos         鏀朵欢浜哄垪琛�
-     * @param ccs         鎶勯�佷汉鍒楄〃锛屽彲浠ヤ负null鎴栫┖
-     * @param bccs        瀵嗛�佷汉鍒楄〃锛屽彲浠ヤ负null鎴栫┖
-     * @param subject     鏍囬
-     * @param content     姝f枃
-     * @param isHtml      鏄惁涓篐TML鏍煎紡
-     * @param files       闄勪欢鍒楄〃
-     * @return message-id
-     * @since 4.0.3
-     */
-    public static String send(MailAccount mailAccount, Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content, boolean isHtml, File... files) {
-        return send(mailAccount, false, tos, ccs, bccs, subject, content, null, isHtml, files);
-    }
-
-    /**
-     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�丠TML閭欢锛屽彂閫佺粰鍗曚釜鎴栧涓敹浠朵汉<br>
-     * 澶氫釜鏀朵欢浜哄彲浠ヤ娇鐢ㄩ�楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
-     *
-     * @param to       鏀朵欢浜�
-     * @param subject  鏍囬
-     * @param content  姝f枃
-     * @param imageMap 鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:$IMAGE_PLACEHOLDER
-     * @param files    闄勪欢鍒楄〃
-     * @return message-id
-     * @since 3.2.0
-     */
-    public static String sendHtml(String to, String subject, String content, Map<String, InputStream> imageMap, File... files) {
-        return send(to, subject, content, imageMap, true, files);
-    }
-
-    /**
-     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�侀偖浠讹紝鍙戦�佸崟涓垨澶氫釜鏀朵欢浜�<br>
-     * 澶氫釜鏀朵欢浜哄彲浠ヤ娇鐢ㄩ�楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
-     *
-     * @param to       鏀朵欢浜�
-     * @param subject  鏍囬
-     * @param content  姝f枃
-     * @param imageMap 鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:$IMAGE_PLACEHOLDER
-     * @param isHtml   鏄惁涓篐TML
-     * @param files    闄勪欢鍒楄〃
-     * @return message-id
-     */
-    public static String send(String to, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) {
-        return send(splitAddress(to), subject, content, imageMap, isHtml, files);
-    }
-
-    /**
-     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�侀偖浠讹紝鍙戦�佸崟涓垨澶氫釜鏀朵欢浜�<br>
-     * 澶氫釜鏀朵欢浜恒�佹妱閫佷汉銆佸瘑閫佷汉鍙互浣跨敤閫楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
-     *
-     * @param to       鏀朵欢浜猴紝鍙互浣跨敤閫楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
-     * @param cc       鎶勯�佷汉锛屽彲浠ヤ娇鐢ㄩ�楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
-     * @param bcc      瀵嗛�佷汉锛屽彲浠ヤ娇鐢ㄩ�楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
-     * @param subject  鏍囬
-     * @param content  姝f枃
-     * @param imageMap 鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:$IMAGE_PLACEHOLDER
-     * @param isHtml   鏄惁涓篐TML
-     * @param files    闄勪欢鍒楄〃
-     * @return message-id
-     * @since 4.0.3
-     */
-    public static String send(String to, String cc, String bcc, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) {
-        return send(splitAddress(to), splitAddress(cc), splitAddress(bcc), subject, content, imageMap, isHtml, files);
-    }
-
-    /**
-     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�丠TML閭欢锛屽彂閫佺粰澶氫汉
-     *
-     * @param tos      鏀朵欢浜哄垪琛�
-     * @param subject  鏍囬
-     * @param content  姝f枃
-     * @param imageMap 鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:$IMAGE_PLACEHOLDER
-     * @param files    闄勪欢鍒楄〃
-     * @return message-id
-     * @since 3.2.0
-     */
-    public static String sendHtml(Collection<String> tos, String subject, String content, Map<String, InputStream> imageMap, File... files) {
-        return send(tos, subject, content, imageMap, true, files);
-    }
-
-    /**
-     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�侀偖浠讹紝鍙戦�佺粰澶氫汉
-     *
-     * @param tos      鏀朵欢浜哄垪琛�
-     * @param subject  鏍囬
-     * @param content  姝f枃
-     * @param imageMap 鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:$IMAGE_PLACEHOLDER
-     * @param isHtml   鏄惁涓篐TML
-     * @param files    闄勪欢鍒楄〃
-     * @return message-id
-     */
-    public static String send(Collection<String> tos, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) {
-        return send(tos, null, null, subject, content, imageMap, isHtml, files);
-    }
-
-    /**
-     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�侀偖浠讹紝鍙戦�佺粰澶氫汉
-     *
-     * @param tos      鏀朵欢浜哄垪琛�
-     * @param ccs      鎶勯�佷汉鍒楄〃锛屽彲浠ヤ负null鎴栫┖
-     * @param bccs     瀵嗛�佷汉鍒楄〃锛屽彲浠ヤ负null鎴栫┖
-     * @param subject  鏍囬
-     * @param content  姝f枃
-     * @param imageMap 鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:$IMAGE_PLACEHOLDER
-     * @param isHtml   鏄惁涓篐TML
-     * @param files    闄勪欢鍒楄〃
-     * @return message-id
-     * @since 4.0.3
-     */
-    public static String send(Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) {
-        return send(getMailAccount(), true, tos, ccs, bccs, subject, content, imageMap, isHtml, files);
-    }
-
-    // ------------------------------------------------------------------------------------------------------------------------------- Custom MailAccount
-
-    /**
-     * 鍙戦�侀偖浠剁粰澶氫汉
-     *
-     * @param mailAccount 閭欢璁よ瘉瀵硅薄
-     * @param to          鏀朵欢浜猴紝澶氫釜鏀朵欢浜洪�楀彿鎴栬�呭垎鍙烽殧寮�
-     * @param subject     鏍囬
-     * @param content     姝f枃
-     * @param imageMap    鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:$IMAGE_PLACEHOLDER
-     * @param isHtml      鏄惁涓篐TML鏍煎紡
-     * @param files       闄勪欢鍒楄〃
-     * @return message-id
-     * @since 3.2.0
-     */
-    public static String send(MailAccount mailAccount, String to, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) {
-        return send(mailAccount, splitAddress(to), subject, content, imageMap, isHtml, files);
-    }
-
-    /**
-     * 鍙戦�侀偖浠剁粰澶氫汉
-     *
-     * @param mailAccount 閭欢甯愭埛淇℃伅
-     * @param tos         鏀朵欢浜哄垪琛�
-     * @param subject     鏍囬
-     * @param content     姝f枃
-     * @param imageMap    鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:$IMAGE_PLACEHOLDER
-     * @param isHtml      鏄惁涓篐TML鏍煎紡
-     * @param files       闄勪欢鍒楄〃
-     * @return message-id
-     * @since 4.6.3
-     */
-    public static String send(MailAccount mailAccount, Collection<String> tos, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) {
-        return send(mailAccount, tos, null, null, subject, content, imageMap, isHtml, files);
-    }
-
-    /**
-     * 鍙戦�侀偖浠剁粰澶氫汉
-     *
-     * @param mailAccount 閭欢甯愭埛淇℃伅
-     * @param tos         鏀朵欢浜哄垪琛�
-     * @param ccs         鎶勯�佷汉鍒楄〃锛屽彲浠ヤ负null鎴栫┖
-     * @param bccs        瀵嗛�佷汉鍒楄〃锛屽彲浠ヤ负null鎴栫┖
-     * @param subject     鏍囬
-     * @param content     姝f枃
-     * @param imageMap    鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:$IMAGE_PLACEHOLDER
-     * @param isHtml      鏄惁涓篐TML鏍煎紡
-     * @param files       闄勪欢鍒楄〃
-     * @return message-id
-     * @since 4.6.3
-     */
-    public static String send(MailAccount mailAccount, Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content, Map<String, InputStream> imageMap,
-                              boolean isHtml, File... files) {
-        return send(mailAccount, false, tos, ccs, bccs, subject, content, imageMap, isHtml, files);
-    }
-
-    /**
-     * 鏍规嵁閰嶇疆鏂囦欢锛岃幏鍙栭偖浠跺鎴风浼氳瘽
-     *
-     * @param mailAccount 閭欢璐︽埛閰嶇疆
-     * @param isSingleton 鏄惁鍗曚緥锛堝叏灞�鍏变韩浼氳瘽锛�
-     * @return {@link Session}
-     * @since 5.5.7
-     */
-    public static Session getSession(MailAccount mailAccount, boolean isSingleton) {
-        Authenticator authenticator = null;
-        if (mailAccount.isAuth()) {
-            authenticator = new UserPassAuthenticator(mailAccount.getUser(), mailAccount.getPass());
-        }
-
-        return isSingleton ? Session.getDefaultInstance(mailAccount.getSmtpProps(), authenticator) //
-            : Session.getInstance(mailAccount.getSmtpProps(), authenticator);
-    }
-
-    // ------------------------------------------------------------------------------------------------------------------------ Private method start
-
-    /**
-     * 鍙戦�侀偖浠剁粰澶氫汉
-     *
-     * @param mailAccount      閭欢甯愭埛淇℃伅
-     * @param useGlobalSession 鏄惁鍏ㄥ眬鍏变韩Session
-     * @param tos              鏀朵欢浜哄垪琛�
-     * @param ccs              鎶勯�佷汉鍒楄〃锛屽彲浠ヤ负null鎴栫┖
-     * @param bccs             瀵嗛�佷汉鍒楄〃锛屽彲浠ヤ负null鎴栫┖
-     * @param subject          鏍囬
-     * @param content          姝f枃
-     * @param imageMap         鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:${cid}
-     * @param isHtml           鏄惁涓篐TML鏍煎紡
-     * @param files            闄勪欢鍒楄〃
-     * @return message-id
-     * @since 4.6.3
-     */
-    private static String send(MailAccount mailAccount, boolean useGlobalSession, Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content,
-                               Map<String, InputStream> imageMap, boolean isHtml, File... files) {
-        final Mail mail = Mail.create(mailAccount).setUseGlobalSession(useGlobalSession);
-
-        // 鍙�夋妱閫佷汉
-        if (CollUtil.isNotEmpty(ccs)) {
-            mail.setCcs(ccs.toArray(new String[0]));
-        }
-        // 鍙�夊瘑閫佷汉
-        if (CollUtil.isNotEmpty(bccs)) {
-            mail.setBccs(bccs.toArray(new String[0]));
-        }
-
-        mail.setTos(tos.toArray(new String[0]));
-        mail.setTitle(subject);
-        mail.setContent(content);
-        mail.setHtml(isHtml);
-        mail.setFiles(files);
-
-        // 鍥剧墖
-        if (MapUtil.isNotEmpty(imageMap)) {
-            for (Map.Entry<String, InputStream> entry : imageMap.entrySet()) {
-                mail.addImage(entry.getKey(), entry.getValue());
-                // 鍏抽棴娴�
-                IoUtil.close(entry.getValue());
-            }
-        }
-
-        return mail.send();
-    }
-
-    /**
-     * 灏嗗涓仈绯讳汉杞负鍒楄〃锛屽垎闅旂涓洪�楀彿鎴栬�呭垎鍙�
-     *
-     * @param addresses 澶氫釜鑱旂郴浜猴紝濡傛灉涓虹┖杩斿洖null
-     * @return 鑱旂郴浜哄垪琛�
-     */
-    private static List<String> splitAddress(String addresses) {
-        if (StrUtil.isBlank(addresses)) {
-            return null;
-        }
-
-        List<String> result;
-        if (StrUtil.contains(addresses, CharUtil.COMMA)) {
-            result = StrUtil.splitTrim(addresses, CharUtil.COMMA);
-        } else if (StrUtil.contains(addresses, ';')) {
-            result = StrUtil.splitTrim(addresses, ';');
-        } else {
-            result = CollUtil.newArrayList(addresses);
-        }
-        return result;
-    }
-    // ------------------------------------------------------------------------------------------------------------------------ Private method end
-
-}
diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/com/ruoyi/common/mail/utils/UserPassAuthenticator.java b/ruoyi-common/ruoyi-common-mail/src/main/java/com/ruoyi/common/mail/utils/UserPassAuthenticator.java
deleted file mode 100644
index 8d4d6f3..0000000
--- a/ruoyi-common/ruoyi-common-mail/src/main/java/com/ruoyi/common/mail/utils/UserPassAuthenticator.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.ruoyi.common.mail.utils;
-
-import jakarta.mail.Authenticator;
-import jakarta.mail.PasswordAuthentication;
-
-/**
- * 鐢ㄦ埛鍚嶅瘑鐮侀獙璇佸櫒
- *
- * @author looly
- * @since 3.1.2
- */
-public class UserPassAuthenticator extends Authenticator {
-
-	private final String user;
-	private final String pass;
-
-	/**
-	 * 鏋勯��
-	 *
-	 * @param user 鐢ㄦ埛鍚�
-	 * @param pass 瀵嗙爜
-	 */
-	public UserPassAuthenticator(String user, String pass) {
-		this.user = user;
-		this.pass = pass;
-	}
-
-	@Override
-	protected PasswordAuthentication getPasswordAuthentication() {
-		return new PasswordAuthentication(this.user, this.pass);
-	}
-
-}
diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/MailConfig.java b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/MailConfig.java
new file mode 100644
index 0000000..0ea3007
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/MailConfig.java
@@ -0,0 +1,37 @@
+package org.dromara.common.mail.config;
+
+import cn.hutool.extra.mail.MailAccount;
+import org.dromara.common.mail.config.properties.MailProperties;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * JavaMail 閰嶇疆
+ *
+ * @author Michelle.Chung
+ */
+@AutoConfiguration
+@EnableConfigurationProperties(MailProperties.class)
+public class MailConfig {
+
+    @Bean
+    @ConditionalOnProperty(value = "mail.enabled", havingValue = "true")
+    public MailAccount mailAccount(MailProperties mailProperties) {
+        MailAccount account = new MailAccount();
+        account.setHost(mailProperties.getHost());
+        account.setPort(mailProperties.getPort());
+        account.setAuth(mailProperties.getAuth());
+        account.setFrom(mailProperties.getFrom());
+        account.setUser(mailProperties.getUser());
+        account.setPass(mailProperties.getPass());
+        account.setSocketFactoryPort(mailProperties.getPort());
+        account.setStarttlsEnable(mailProperties.getStarttlsEnable());
+        account.setSslEnable(mailProperties.getSslEnable());
+        account.setTimeout(mailProperties.getTimeout());
+        account.setConnectionTimeout(mailProperties.getConnectionTimeout());
+        return account;
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/properties/MailProperties.java b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/properties/MailProperties.java
new file mode 100644
index 0000000..d0e78a2
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/properties/MailProperties.java
@@ -0,0 +1,69 @@
+package org.dromara.common.mail.config.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * JavaMail 閰嶇疆灞炴��
+ *
+ * @author Michelle.Chung
+ */
+@Data
+@ConfigurationProperties(prefix = "mail")
+public class MailProperties {
+
+    /**
+     * 杩囨护寮�鍏�
+     */
+    private Boolean enabled;
+
+    /**
+     * SMTP鏈嶅姟鍣ㄥ煙鍚�
+     */
+    private String host;
+
+    /**
+     * SMTP鏈嶅姟绔彛
+     */
+    private Integer port;
+
+    /**
+     * 鏄惁闇�瑕佺敤鎴峰悕瀵嗙爜楠岃瘉
+     */
+    private Boolean auth;
+
+    /**
+     * 鐢ㄦ埛鍚�
+     */
+    private String user;
+
+    /**
+     * 瀵嗙爜
+     */
+    private String pass;
+
+    /**
+     * 鍙戦�佹柟锛岄伒寰猂FC-822鏍囧噯
+     */
+    private String from;
+
+    /**
+     * 浣跨敤 STARTTLS瀹夊叏杩炴帴锛孲TARTTLS鏄绾枃鏈�氫俊鍗忚鐨勬墿灞曘�傚畠灏嗙函鏂囨湰杩炴帴鍗囩骇涓哄姞瀵嗚繛鎺ワ紙TLS鎴朣SL锛夛紝 鑰屼笉鏄娇鐢ㄤ竴涓崟鐙殑鍔犲瘑閫氫俊绔彛銆�
+     */
+    private Boolean starttlsEnable;
+
+    /**
+     * 浣跨敤 SSL瀹夊叏杩炴帴
+     */
+    private Boolean sslEnable;
+
+    /**
+     * SMTP瓒呮椂鏃堕暱锛屽崟浣嶆绉掞紝缂虹渷鍊间笉瓒呮椂
+     */
+    private Long timeout;
+
+    /**
+     * Socket杩炴帴瓒呮椂鍊硷紝鍗曚綅姣锛岀己鐪佸�间笉瓒呮椂
+     */
+    private Long connectionTimeout;
+}
diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/InternalMailUtil.java b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/InternalMailUtil.java
new file mode 100644
index 0000000..34a9a78
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/InternalMailUtil.java
@@ -0,0 +1,108 @@
+package org.dromara.common.mail.utils;
+
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.extra.mail.MailException;
+import jakarta.mail.internet.AddressException;
+import jakarta.mail.internet.InternetAddress;
+import jakarta.mail.internet.MimeUtility;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * 閭欢鍐呴儴宸ュ叿绫�
+ * @author looly
+ * @since 3.2.3
+ */
+public class InternalMailUtil {
+
+	/**
+	 * 灏嗗涓瓧绗︿覆閭欢鍦板潃杞负{@link InternetAddress}鍒楄〃<br>
+	 * 鍗曚釜瀛楃涓插湴鍧�鍙互鏄涓湴鍧�鍚堝苟鐨勫瓧绗︿覆
+	 *
+	 * @param addrStrs 鍦板潃鏁扮粍
+	 * @param charset 缂栫爜锛堜富瑕佺敤浜庝腑鏂囩敤鎴峰悕鐨勭紪鐮侊級
+	 * @return 鍦板潃鏁扮粍
+	 * @since 4.0.3
+	 */
+	public static InternetAddress[] parseAddressFromStrs(String[] addrStrs, Charset charset) {
+		final List<InternetAddress> resultList = new ArrayList<>(addrStrs.length);
+		InternetAddress[] addrs;
+		for (String addrStr : addrStrs) {
+			addrs = parseAddress(addrStr, charset);
+			if (ArrayUtil.isNotEmpty(addrs)) {
+				Collections.addAll(resultList, addrs);
+			}
+		}
+		return resultList.toArray(new InternetAddress[0]);
+	}
+
+	/**
+	 * 瑙f瀽绗竴涓湴鍧�
+	 *
+	 * @param address 鍦板潃瀛楃涓�
+	 * @param charset 缂栫爜锛寋@code null}琛ㄧず浣跨敤绯荤粺灞炴�у畾涔夌殑缂栫爜鎴栫郴缁熺紪鐮�
+	 * @return 鍦板潃鍒楄〃
+	 */
+	public static InternetAddress parseFirstAddress(String address, Charset charset) {
+		final InternetAddress[] internetAddresses = parseAddress(address, charset);
+		if (ArrayUtil.isEmpty(internetAddresses)) {
+			try {
+				return new InternetAddress(address);
+			} catch (AddressException e) {
+				throw new MailException(e);
+			}
+		}
+		return internetAddresses[0];
+	}
+
+	/**
+	 * 灏嗕竴涓湴鍧�瀛楃涓茶В鏋愪负澶氫釜鍦板潃<br>
+	 * 鍦板潃闂翠娇鐢�" "銆�","銆�";"鍒嗛殧
+	 *
+	 * @param address 鍦板潃瀛楃涓�
+	 * @param charset 缂栫爜锛寋@code null}琛ㄧず浣跨敤绯荤粺灞炴�у畾涔夌殑缂栫爜鎴栫郴缁熺紪鐮�
+	 * @return 鍦板潃鍒楄〃
+	 */
+	public static InternetAddress[] parseAddress(String address, Charset charset) {
+		InternetAddress[] addresses;
+		try {
+			addresses = InternetAddress.parse(address);
+		} catch (AddressException e) {
+			throw new MailException(e);
+		}
+		//缂栫爜鐢ㄦ埛鍚�
+		if (ArrayUtil.isNotEmpty(addresses)) {
+			final String charsetStr = null == charset ? null : charset.name();
+			for (InternetAddress internetAddress : addresses) {
+				try {
+					internetAddress.setPersonal(internetAddress.getPersonal(), charsetStr);
+				} catch (UnsupportedEncodingException e) {
+					throw new MailException(e);
+				}
+			}
+		}
+
+		return addresses;
+	}
+
+	/**
+	 * 缂栫爜涓枃瀛楃<br>
+	 * 缂栫爜澶辫触杩斿洖鍘熷瓧绗︿覆
+	 *
+	 * @param text 琚紪鐮佺殑鏂囨湰
+	 * @param charset 缂栫爜
+	 * @return 缂栫爜鍚庣殑缁撴灉
+	 */
+	public static String encodeText(String text, Charset charset) {
+		try {
+			return MimeUtility.encodeText(text, charset.name(), null);
+		} catch (UnsupportedEncodingException e) {
+			// ignore
+		}
+		return text;
+	}
+}
diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/Mail.java b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/Mail.java
new file mode 100644
index 0000000..4f5a88e
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/Mail.java
@@ -0,0 +1,486 @@
+package org.dromara.common.mail.utils;
+
+import cn.hutool.core.builder.Builder;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.IORuntimeException;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.mail.*;
+import jakarta.activation.DataHandler;
+import jakarta.activation.DataSource;
+import jakarta.activation.FileDataSource;
+import jakarta.activation.FileTypeMap;
+import jakarta.mail.*;
+import jakarta.mail.internet.MimeBodyPart;
+import jakarta.mail.internet.MimeMessage;
+import jakarta.mail.internet.MimeMultipart;
+import jakarta.mail.internet.MimeUtility;
+import jakarta.mail.util.ByteArrayDataSource;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.nio.charset.Charset;
+import java.util.Date;
+
+/**
+ * 閭欢鍙戦�佸鎴风
+ *
+ * @author looly
+ * @since 3.2.0
+ */
+public class Mail implements Builder<MimeMessage> {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 閭甯愭埛淇℃伅浠ュ強涓�浜涘鎴风閰嶇疆淇℃伅
+	 */
+	private final MailAccount mailAccount;
+	/**
+	 * 鏀朵欢浜哄垪琛�
+	 */
+	private String[] tos;
+	/**
+	 * 鎶勯�佷汉鍒楄〃锛坈arbon copy锛�
+	 */
+	private String[] ccs;
+	/**
+	 * 瀵嗛�佷汉鍒楄〃锛坆lind carbon copy锛�
+	 */
+	private String[] bccs;
+	/**
+	 * 鍥炲鍦板潃(reply-to)
+	 */
+	private String[] reply;
+	/**
+	 * 鏍囬
+	 */
+	private String title;
+	/**
+	 * 鍐呭
+	 */
+	private String content;
+	/**
+	 * 鏄惁涓篐TML
+	 */
+	private boolean isHtml;
+	/**
+	 * 姝f枃銆侀檮浠跺拰鍥剧墖鐨勬贩鍚堥儴鍒�
+	 */
+	private final Multipart multipart = new MimeMultipart();
+	/**
+	 * 鏄惁浣跨敤鍏ㄥ眬浼氳瘽锛岄粯璁や负false
+	 */
+	private boolean useGlobalSession = false;
+
+	/**
+	 * debug杈撳嚭浣嶇疆锛屽彲浠ヨ嚜瀹氫箟debug鏃ュ織
+	 */
+	private PrintStream debugOutput;
+
+	/**
+	 * 鍒涘缓閭欢瀹㈡埛绔�
+	 *
+	 * @param mailAccount 閭欢甯愬彿
+	 * @return Mail
+	 */
+	public static Mail create(MailAccount mailAccount) {
+		return new Mail(mailAccount);
+	}
+
+	/**
+	 * 鍒涘缓閭欢瀹㈡埛绔紝浣跨敤鍏ㄥ眬閭欢甯愭埛
+	 *
+	 * @return Mail
+	 */
+	public static Mail create() {
+		return new Mail();
+	}
+
+	// --------------------------------------------------------------- Constructor start
+
+	/**
+	 * 鏋勯�狅紝浣跨敤鍏ㄥ眬閭欢甯愭埛
+	 */
+	public Mail() {
+		this(GlobalMailAccount.INSTANCE.getAccount());
+	}
+
+	/**
+	 * 鏋勯��
+	 *
+	 * @param mailAccount 閭欢甯愭埛锛屽鏋滀负null浣跨敤榛樿閰嶇疆鏂囦欢鐨勫叏灞�閭欢閰嶇疆
+	 */
+	public Mail(MailAccount mailAccount) {
+		mailAccount = (null != mailAccount) ? mailAccount : GlobalMailAccount.INSTANCE.getAccount();
+		this.mailAccount = mailAccount.defaultIfEmpty();
+	}
+	// --------------------------------------------------------------- Constructor end
+
+	// --------------------------------------------------------------- Getters and Setters start
+
+	/**
+	 * 璁剧疆鏀朵欢浜�
+	 *
+	 * @param tos 鏀朵欢浜哄垪琛�
+	 * @return this
+	 * @see #setTos(String...)
+	 */
+	public Mail to(String... tos) {
+		return setTos(tos);
+	}
+
+	/**
+	 * 璁剧疆澶氫釜鏀朵欢浜�
+	 *
+	 * @param tos 鏀朵欢浜哄垪琛�
+	 * @return this
+	 */
+	public Mail setTos(String... tos) {
+		this.tos = tos;
+		return this;
+	}
+
+	/**
+	 * 璁剧疆澶氫釜鎶勯�佷汉锛坈arbon copy锛�
+	 *
+	 * @param ccs 鎶勯�佷汉鍒楄〃
+	 * @return this
+	 * @since 4.0.3
+	 */
+	public Mail setCcs(String... ccs) {
+		this.ccs = ccs;
+		return this;
+	}
+
+	/**
+	 * 璁剧疆澶氫釜瀵嗛�佷汉锛坆lind carbon copy锛�
+	 *
+	 * @param bccs 瀵嗛�佷汉鍒楄〃
+	 * @return this
+	 * @since 4.0.3
+	 */
+	public Mail setBccs(String... bccs) {
+		this.bccs = bccs;
+		return this;
+	}
+
+	/**
+	 * 璁剧疆澶氫釜鍥炲鍦板潃(reply-to)
+	 *
+	 * @param reply 鍥炲鍦板潃(reply-to)鍒楄〃
+	 * @return this
+	 * @since 4.6.0
+	 */
+	public Mail setReply(String... reply) {
+		this.reply = reply;
+		return this;
+	}
+
+	/**
+	 * 璁剧疆鏍囬
+	 *
+	 * @param title 鏍囬
+	 * @return this
+	 */
+	public Mail setTitle(String title) {
+		this.title = title;
+		return this;
+	}
+
+	/**
+	 * 璁剧疆姝f枃<br>
+	 * 姝f枃鍙互鏄櫘閫氭枃鏈篃鍙互鏄疕TML锛堥粯璁ゆ櫘閫氭枃鏈級锛屽彲浠ラ�氳繃璋冪敤{@link #setHtml(boolean)} 璁剧疆鏄惁涓篐TML
+	 *
+	 * @param content 姝f枃
+	 * @return this
+	 */
+	public Mail setContent(String content) {
+		this.content = content;
+		return this;
+	}
+
+	/**
+	 * 璁剧疆鏄惁鏄疕TML
+	 *
+	 * @param isHtml 鏄惁涓篐TML
+	 * @return this
+	 */
+	public Mail setHtml(boolean isHtml) {
+		this.isHtml = isHtml;
+		return this;
+	}
+
+	/**
+	 * 璁剧疆姝f枃
+	 *
+	 * @param content 姝f枃鍐呭
+	 * @param isHtml  鏄惁涓篐TML
+	 * @return this
+	 */
+	public Mail setContent(String content, boolean isHtml) {
+		setContent(content);
+		return setHtml(isHtml);
+	}
+
+	/**
+	 * 璁剧疆鏂囦欢绫诲瀷闄勪欢锛屾枃浠跺彲浠ユ槸鍥剧墖鏂囦欢锛屾鏃惰嚜鍔ㄨ缃甤id锛堟鏂囦腑寮曠敤鍥剧墖锛夛紝榛樿cid涓烘枃浠跺悕
+	 *
+	 * @param files 闄勪欢鏂囦欢鍒楄〃
+	 * @return this
+	 */
+	public Mail setFiles(File... files) {
+		if (ArrayUtil.isEmpty(files)) {
+			return this;
+		}
+
+		final DataSource[] attachments = new DataSource[files.length];
+		for (int i = 0; i < files.length; i++) {
+			attachments[i] = new FileDataSource(files[i]);
+		}
+		return setAttachments(attachments);
+	}
+
+	/**
+	 * 澧炲姞闄勪欢鎴栧浘鐗囷紝闄勪欢浣跨敤{@link DataSource} 褰㈠紡琛ㄧず锛屽彲浠ヤ娇鐢▄@link FileDataSource}鍖呰鏂囦欢琛ㄧず鏂囦欢闄勪欢
+	 *
+	 * @param attachments 闄勪欢鍒楄〃
+	 * @return this
+	 * @since 4.0.9
+	 */
+	public Mail setAttachments(DataSource... attachments) {
+		if (ArrayUtil.isNotEmpty(attachments)) {
+			final Charset charset = this.mailAccount.getCharset();
+			MimeBodyPart bodyPart;
+			String nameEncoded;
+			try {
+				for (DataSource attachment : attachments) {
+					bodyPart = new MimeBodyPart();
+					bodyPart.setDataHandler(new DataHandler(attachment));
+					nameEncoded = attachment.getName();
+					if (this.mailAccount.isEncodefilename()) {
+						nameEncoded = org.dromara.common.mail.utils.InternalMailUtil.encodeText(nameEncoded, charset);
+					}
+					// 鏅�氶檮浠舵枃浠跺悕
+					bodyPart.setFileName(nameEncoded);
+					if (StrUtil.startWith(attachment.getContentType(), "image/")) {
+						// 鍥剧墖闄勪欢锛岀敤浜庢鏂囦腑寮曠敤鍥剧墖
+						bodyPart.setContentID(nameEncoded);
+					}
+					this.multipart.addBodyPart(bodyPart);
+				}
+			} catch (MessagingException e) {
+				throw new MailException(e);
+			}
+		}
+		return this;
+	}
+
+	/**
+	 * 澧炲姞鍥剧墖锛屽浘鐗囩殑閿搴斿埌閭欢妯℃澘涓殑鍗犱綅瀛楃涓诧紝鍥剧墖绫诲瀷榛樿涓�"image/jpeg"
+	 *
+	 * @param cid         鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:${cid}
+	 * @param imageStream 鍥剧墖鏂囦欢
+	 * @return this
+	 * @since 4.6.3
+	 */
+	public Mail addImage(String cid, InputStream imageStream) {
+		return addImage(cid, imageStream, null);
+	}
+
+	/**
+	 * 澧炲姞鍥剧墖锛屽浘鐗囩殑閿搴斿埌閭欢妯℃澘涓殑鍗犱綅瀛楃涓�
+	 *
+	 * @param cid         鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:${cid}
+	 * @param imageStream 鍥剧墖娴侊紝涓嶅叧闂�
+	 * @param contentType 鍥剧墖绫诲瀷锛宯ull璧嬪�奸粯璁ょ殑"image/jpeg"
+	 * @return this
+	 * @since 4.6.3
+	 */
+	public Mail addImage(String cid, InputStream imageStream, String contentType) {
+		ByteArrayDataSource imgSource;
+		try {
+			imgSource = new ByteArrayDataSource(imageStream, ObjectUtil.defaultIfNull(contentType, "image/jpeg"));
+		} catch (IOException e) {
+			throw new IORuntimeException(e);
+		}
+		imgSource.setName(cid);
+		return setAttachments(imgSource);
+	}
+
+	/**
+	 * 澧炲姞鍥剧墖锛屽浘鐗囩殑閿搴斿埌閭欢妯℃澘涓殑鍗犱綅瀛楃涓�
+	 *
+	 * @param cid       鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:${cid}
+	 * @param imageFile 鍥剧墖鏂囦欢
+	 * @return this
+	 * @since 4.6.3
+	 */
+	public Mail addImage(String cid, File imageFile) {
+		InputStream in = null;
+		try {
+			in = FileUtil.getInputStream(imageFile);
+			return addImage(cid, in, FileTypeMap.getDefaultFileTypeMap().getContentType(imageFile));
+		} finally {
+			IoUtil.close(in);
+		}
+	}
+
+	/**
+	 * 璁剧疆瀛楃闆嗙紪鐮�
+	 *
+	 * @param charset 瀛楃闆嗙紪鐮�
+	 * @return this
+	 * @see MailAccount#setCharset(Charset)
+	 */
+	public Mail setCharset(Charset charset) {
+		this.mailAccount.setCharset(charset);
+		return this;
+	}
+
+	/**
+	 * 璁剧疆鏄惁浣跨敤鍏ㄥ眬浼氳瘽锛岄粯璁や负true
+	 *
+	 * @param isUseGlobalSession 鏄惁浣跨敤鍏ㄥ眬浼氳瘽锛岄粯璁や负true
+	 * @return this
+	 * @since 4.0.2
+	 */
+	public Mail setUseGlobalSession(boolean isUseGlobalSession) {
+		this.useGlobalSession = isUseGlobalSession;
+		return this;
+	}
+
+	/**
+	 * 璁剧疆debug杈撳嚭浣嶇疆锛屽彲浠ヨ嚜瀹氫箟debug鏃ュ織
+	 *
+	 * @param debugOutput debug杈撳嚭浣嶇疆
+	 * @return this
+	 * @since 5.5.6
+	 */
+	public Mail setDebugOutput(PrintStream debugOutput) {
+		this.debugOutput = debugOutput;
+		return this;
+	}
+	// --------------------------------------------------------------- Getters and Setters end
+
+	@Override
+	public MimeMessage build() {
+		try {
+			return buildMsg();
+		} catch (MessagingException e) {
+			throw new MailException(e);
+		}
+	}
+
+	/**
+	 * 鍙戦��
+	 *
+	 * @return message-id
+	 * @throws MailException 閭欢鍙戦�佸紓甯�
+	 */
+	public String send() throws MailException {
+		try {
+			return doSend();
+		} catch (MessagingException e) {
+			if (e instanceof SendFailedException) {
+				// 褰撳湴鍧�鏃犳晥鏃讹紝鏄剧ず鏇村姞璇︾粏鐨勬棤鏁堝湴鍧�淇℃伅
+				final Address[] invalidAddresses = ((SendFailedException) e).getInvalidAddresses();
+				final String msg = StrUtil.format("Invalid Addresses: {}", ArrayUtil.toString(invalidAddresses));
+				throw new MailException(msg, e);
+			}
+			throw new MailException(e);
+		}
+	}
+
+	// --------------------------------------------------------------- Private method start
+
+	/**
+	 * 鎵ц鍙戦��
+	 *
+	 * @return message-id
+	 * @throws MessagingException 鍙戦�佸紓甯�
+	 */
+	private String doSend() throws MessagingException {
+		final MimeMessage mimeMessage = buildMsg();
+		Transport.send(mimeMessage);
+		return mimeMessage.getMessageID();
+	}
+
+	/**
+	 * 鏋勫缓娑堟伅
+	 *
+	 * @return {@link MimeMessage}娑堟伅
+	 * @throws MessagingException 娑堟伅寮傚父
+	 */
+	private MimeMessage buildMsg() throws MessagingException {
+		final Charset charset = this.mailAccount.getCharset();
+		final MimeMessage msg = new MimeMessage(getSession());
+		// 鍙戜欢浜�
+		final String from = this.mailAccount.getFrom();
+		if (StrUtil.isEmpty(from)) {
+			// 鐢ㄦ埛鏈彁渚涘彂閫佹柟锛屽垯浠嶴ession涓嚜鍔ㄨ幏鍙�
+			msg.setFrom();
+		} else {
+			msg.setFrom(org.dromara.common.mail.utils.InternalMailUtil.parseFirstAddress(from, charset));
+		}
+		// 鏍囬
+		msg.setSubject(this.title, (null == charset) ? null : charset.name());
+		// 鍙戦�佹椂闂�
+		msg.setSentDate(new Date());
+		// 鍐呭鍜岄檮浠�
+		msg.setContent(buildContent(charset));
+		// 鏀朵欢浜�
+		msg.setRecipients(MimeMessage.RecipientType.TO, org.dromara.common.mail.utils.InternalMailUtil.parseAddressFromStrs(this.tos, charset));
+		// 鎶勯�佷汉
+		if (ArrayUtil.isNotEmpty(this.ccs)) {
+			msg.setRecipients(MimeMessage.RecipientType.CC, org.dromara.common.mail.utils.InternalMailUtil.parseAddressFromStrs(this.ccs, charset));
+		}
+		// 瀵嗛�佷汉
+		if (ArrayUtil.isNotEmpty(this.bccs)) {
+			msg.setRecipients(MimeMessage.RecipientType.BCC, org.dromara.common.mail.utils.InternalMailUtil.parseAddressFromStrs(this.bccs, charset));
+		}
+		// 鍥炲鍦板潃(reply-to)
+		if (ArrayUtil.isNotEmpty(this.reply)) {
+			msg.setReplyTo(InternalMailUtil.parseAddressFromStrs(this.reply, charset));
+		}
+
+		return msg;
+	}
+
+	/**
+	 * 鏋勫缓閭欢淇℃伅涓讳綋
+	 *
+	 * @param charset 缂栫爜锛寋@code null}鍒欎娇鐢▄@link MimeUtility#getDefaultJavaCharset()}
+	 * @return 閭欢淇℃伅涓讳綋
+	 * @throws MessagingException 娑堟伅寮傚父
+	 */
+	private Multipart buildContent(Charset charset) throws MessagingException {
+		final String charsetStr = null != charset ? charset.name() : MimeUtility.getDefaultJavaCharset();
+		// 姝f枃
+		final MimeBodyPart body = new MimeBodyPart();
+		body.setContent(content, StrUtil.format("text/{}; charset={}", isHtml ? "html" : "plain", charsetStr));
+		this.multipart.addBodyPart(body);
+
+		return this.multipart;
+	}
+
+	/**
+	 * 鑾峰彇榛樿閭欢浼氳瘽<br>
+	 * 濡傛灉涓哄叏灞�鍗曚緥鐨勪細璇濓紝鍒欏叏灞�鍙厑璁镐竴涓偖浠跺笎鍙凤紝鍚﹀垯姣忔鍙戦�侀偖浠朵細鏂板缓涓�涓柊鐨勪細璇�
+	 *
+	 * @return 閭欢浼氳瘽 {@link Session}
+	 */
+	private Session getSession() {
+		final Session session = MailUtils.getSession(this.mailAccount, this.useGlobalSession);
+
+		if (null != this.debugOutput) {
+			session.setDebugOut(debugOutput);
+		}
+
+		return session;
+	}
+	// --------------------------------------------------------------- Private method end
+}
diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailUtils.java b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailUtils.java
new file mode 100644
index 0000000..177a545
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailUtils.java
@@ -0,0 +1,469 @@
+package org.dromara.common.mail.utils;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.util.CharUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.mail.*;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.StringUtils;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import jakarta.mail.Authenticator;
+import jakarta.mail.Session;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * 閭欢宸ュ叿绫�
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class MailUtils {
+
+    private static final MailAccount ACCOUNT = SpringUtils.getBean(MailAccount.class);
+
+    /**
+     * 鑾峰彇閭欢鍙戦�佸疄渚�
+     */
+    public static MailAccount getMailAccount() {
+        return ACCOUNT;
+    }
+
+    /**
+     * 鑾峰彇閭欢鍙戦�佸疄渚� (鑷畾涔夊彂閫佷汉浠ュ強鎺堟潈鐮�)
+     *
+     * @param user 鍙戦�佷汉
+     * @param pass 鎺堟潈鐮�
+     */
+    public static MailAccount getMailAccount(String from, String user, String pass) {
+        ACCOUNT.setFrom(StringUtils.blankToDefault(from, ACCOUNT.getFrom()));
+        ACCOUNT.setUser(StringUtils.blankToDefault(user, ACCOUNT.getUser()));
+        ACCOUNT.setPass(StringUtils.blankToDefault(pass, ACCOUNT.getPass()));
+        return ACCOUNT;
+    }
+
+    /**
+     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�佹枃鏈偖浠讹紝鍙戦�佺粰鍗曚釜鎴栧涓敹浠朵汉<br>
+     * 澶氫釜鏀朵欢浜哄彲浠ヤ娇鐢ㄩ�楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
+     *
+     * @param to      鏀朵欢浜�
+     * @param subject 鏍囬
+     * @param content 姝f枃
+     * @param files   闄勪欢鍒楄〃
+     * @return message-id
+     * @since 3.2.0
+     */
+    public static String sendText(String to, String subject, String content, File... files) {
+        return send(to, subject, content, false, files);
+    }
+
+    /**
+     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�丠TML閭欢锛屽彂閫佺粰鍗曚釜鎴栧涓敹浠朵汉<br>
+     * 澶氫釜鏀朵欢浜哄彲浠ヤ娇鐢ㄩ�楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
+     *
+     * @param to      鏀朵欢浜�
+     * @param subject 鏍囬
+     * @param content 姝f枃
+     * @param files   闄勪欢鍒楄〃
+     * @return message-id
+     * @since 3.2.0
+     */
+    public static String sendHtml(String to, String subject, String content, File... files) {
+        return send(to, subject, content, true, files);
+    }
+
+    /**
+     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�侀偖浠讹紝鍙戦�佸崟涓垨澶氫釜鏀朵欢浜�<br>
+     * 澶氫釜鏀朵欢浜哄彲浠ヤ娇鐢ㄩ�楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
+     *
+     * @param to      鏀朵欢浜�
+     * @param subject 鏍囬
+     * @param content 姝f枃
+     * @param isHtml  鏄惁涓篐TML
+     * @param files   闄勪欢鍒楄〃
+     * @return message-id
+     */
+    public static String send(String to, String subject, String content, boolean isHtml, File... files) {
+        return send(splitAddress(to), subject, content, isHtml, files);
+    }
+
+    /**
+     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�侀偖浠讹紝鍙戦�佸崟涓垨澶氫釜鏀朵欢浜�<br>
+     * 澶氫釜鏀朵欢浜恒�佹妱閫佷汉銆佸瘑閫佷汉鍙互浣跨敤閫楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
+     *
+     * @param to      鏀朵欢浜猴紝鍙互浣跨敤閫楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
+     * @param cc      鎶勯�佷汉锛屽彲浠ヤ娇鐢ㄩ�楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
+     * @param bcc     瀵嗛�佷汉锛屽彲浠ヤ娇鐢ㄩ�楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
+     * @param subject 鏍囬
+     * @param content 姝f枃
+     * @param isHtml  鏄惁涓篐TML
+     * @param files   闄勪欢鍒楄〃
+     * @return message-id
+     * @since 4.0.3
+     */
+    public static String send(String to, String cc, String bcc, String subject, String content, boolean isHtml, File... files) {
+        return send(splitAddress(to), splitAddress(cc), splitAddress(bcc), subject, content, isHtml, files);
+    }
+
+    /**
+     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�佹枃鏈偖浠讹紝鍙戦�佺粰澶氫汉
+     *
+     * @param tos     鏀朵欢浜哄垪琛�
+     * @param subject 鏍囬
+     * @param content 姝f枃
+     * @param files   闄勪欢鍒楄〃
+     * @return message-id
+     */
+    public static String sendText(Collection<String> tos, String subject, String content, File... files) {
+        return send(tos, subject, content, false, files);
+    }
+
+    /**
+     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�丠TML閭欢锛屽彂閫佺粰澶氫汉
+     *
+     * @param tos     鏀朵欢浜哄垪琛�
+     * @param subject 鏍囬
+     * @param content 姝f枃
+     * @param files   闄勪欢鍒楄〃
+     * @return message-id
+     * @since 3.2.0
+     */
+    public static String sendHtml(Collection<String> tos, String subject, String content, File... files) {
+        return send(tos, subject, content, true, files);
+    }
+
+    /**
+     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�侀偖浠讹紝鍙戦�佺粰澶氫汉
+     *
+     * @param tos     鏀朵欢浜哄垪琛�
+     * @param subject 鏍囬
+     * @param content 姝f枃
+     * @param isHtml  鏄惁涓篐TML
+     * @param files   闄勪欢鍒楄〃
+     * @return message-id
+     */
+    public static String send(Collection<String> tos, String subject, String content, boolean isHtml, File... files) {
+        return send(tos, null, null, subject, content, isHtml, files);
+    }
+
+    /**
+     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�侀偖浠讹紝鍙戦�佺粰澶氫汉
+     *
+     * @param tos     鏀朵欢浜哄垪琛�
+     * @param ccs     鎶勯�佷汉鍒楄〃锛屽彲浠ヤ负null鎴栫┖
+     * @param bccs    瀵嗛�佷汉鍒楄〃锛屽彲浠ヤ负null鎴栫┖
+     * @param subject 鏍囬
+     * @param content 姝f枃
+     * @param isHtml  鏄惁涓篐TML
+     * @param files   闄勪欢鍒楄〃
+     * @return message-id
+     * @since 4.0.3
+     */
+    public static String send(Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content, boolean isHtml, File... files) {
+        return send(getMailAccount(), true, tos, ccs, bccs, subject, content, null, isHtml, files);
+    }
+
+    // ------------------------------------------------------------------------------------------------------------------------------- Custom MailAccount
+
+    /**
+     * 鍙戦�侀偖浠剁粰澶氫汉
+     *
+     * @param mailAccount 閭欢璁よ瘉瀵硅薄
+     * @param to          鏀朵欢浜猴紝澶氫釜鏀朵欢浜洪�楀彿鎴栬�呭垎鍙烽殧寮�
+     * @param subject     鏍囬
+     * @param content     姝f枃
+     * @param isHtml      鏄惁涓篐TML鏍煎紡
+     * @param files       闄勪欢鍒楄〃
+     * @return message-id
+     * @since 3.2.0
+     */
+    public static String send(MailAccount mailAccount, String to, String subject, String content, boolean isHtml, File... files) {
+        return send(mailAccount, splitAddress(to), subject, content, isHtml, files);
+    }
+
+    /**
+     * 鍙戦�侀偖浠剁粰澶氫汉
+     *
+     * @param mailAccount 閭欢甯愭埛淇℃伅
+     * @param tos         鏀朵欢浜哄垪琛�
+     * @param subject     鏍囬
+     * @param content     姝f枃
+     * @param isHtml      鏄惁涓篐TML鏍煎紡
+     * @param files       闄勪欢鍒楄〃
+     * @return message-id
+     */
+    public static String send(MailAccount mailAccount, Collection<String> tos, String subject, String content, boolean isHtml, File... files) {
+        return send(mailAccount, tos, null, null, subject, content, isHtml, files);
+    }
+
+    /**
+     * 鍙戦�侀偖浠剁粰澶氫汉
+     *
+     * @param mailAccount 閭欢甯愭埛淇℃伅
+     * @param tos         鏀朵欢浜哄垪琛�
+     * @param ccs         鎶勯�佷汉鍒楄〃锛屽彲浠ヤ负null鎴栫┖
+     * @param bccs        瀵嗛�佷汉鍒楄〃锛屽彲浠ヤ负null鎴栫┖
+     * @param subject     鏍囬
+     * @param content     姝f枃
+     * @param isHtml      鏄惁涓篐TML鏍煎紡
+     * @param files       闄勪欢鍒楄〃
+     * @return message-id
+     * @since 4.0.3
+     */
+    public static String send(MailAccount mailAccount, Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content, boolean isHtml, File... files) {
+        return send(mailAccount, false, tos, ccs, bccs, subject, content, null, isHtml, files);
+    }
+
+    /**
+     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�丠TML閭欢锛屽彂閫佺粰鍗曚釜鎴栧涓敹浠朵汉<br>
+     * 澶氫釜鏀朵欢浜哄彲浠ヤ娇鐢ㄩ�楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
+     *
+     * @param to       鏀朵欢浜�
+     * @param subject  鏍囬
+     * @param content  姝f枃
+     * @param imageMap 鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:$IMAGE_PLACEHOLDER
+     * @param files    闄勪欢鍒楄〃
+     * @return message-id
+     * @since 3.2.0
+     */
+    public static String sendHtml(String to, String subject, String content, Map<String, InputStream> imageMap, File... files) {
+        return send(to, subject, content, imageMap, true, files);
+    }
+
+    /**
+     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�侀偖浠讹紝鍙戦�佸崟涓垨澶氫釜鏀朵欢浜�<br>
+     * 澶氫釜鏀朵欢浜哄彲浠ヤ娇鐢ㄩ�楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
+     *
+     * @param to       鏀朵欢浜�
+     * @param subject  鏍囬
+     * @param content  姝f枃
+     * @param imageMap 鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:$IMAGE_PLACEHOLDER
+     * @param isHtml   鏄惁涓篐TML
+     * @param files    闄勪欢鍒楄〃
+     * @return message-id
+     */
+    public static String send(String to, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) {
+        return send(splitAddress(to), subject, content, imageMap, isHtml, files);
+    }
+
+    /**
+     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�侀偖浠讹紝鍙戦�佸崟涓垨澶氫釜鏀朵欢浜�<br>
+     * 澶氫釜鏀朵欢浜恒�佹妱閫佷汉銆佸瘑閫佷汉鍙互浣跨敤閫楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
+     *
+     * @param to       鏀朵欢浜猴紝鍙互浣跨敤閫楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
+     * @param cc       鎶勯�佷汉锛屽彲浠ヤ娇鐢ㄩ�楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
+     * @param bcc      瀵嗛�佷汉锛屽彲浠ヤ娇鐢ㄩ�楀彿鈥�,鈥濆垎闅旓紝涔熷彲浠ラ�氳繃鍒嗗彿鈥�;鈥濆垎闅�
+     * @param subject  鏍囬
+     * @param content  姝f枃
+     * @param imageMap 鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:$IMAGE_PLACEHOLDER
+     * @param isHtml   鏄惁涓篐TML
+     * @param files    闄勪欢鍒楄〃
+     * @return message-id
+     * @since 4.0.3
+     */
+    public static String send(String to, String cc, String bcc, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) {
+        return send(splitAddress(to), splitAddress(cc), splitAddress(bcc), subject, content, imageMap, isHtml, files);
+    }
+
+    /**
+     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�丠TML閭欢锛屽彂閫佺粰澶氫汉
+     *
+     * @param tos      鏀朵欢浜哄垪琛�
+     * @param subject  鏍囬
+     * @param content  姝f枃
+     * @param imageMap 鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:$IMAGE_PLACEHOLDER
+     * @param files    闄勪欢鍒楄〃
+     * @return message-id
+     * @since 3.2.0
+     */
+    public static String sendHtml(Collection<String> tos, String subject, String content, Map<String, InputStream> imageMap, File... files) {
+        return send(tos, subject, content, imageMap, true, files);
+    }
+
+    /**
+     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�侀偖浠讹紝鍙戦�佺粰澶氫汉
+     *
+     * @param tos      鏀朵欢浜哄垪琛�
+     * @param subject  鏍囬
+     * @param content  姝f枃
+     * @param imageMap 鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:$IMAGE_PLACEHOLDER
+     * @param isHtml   鏄惁涓篐TML
+     * @param files    闄勪欢鍒楄〃
+     * @return message-id
+     */
+    public static String send(Collection<String> tos, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) {
+        return send(tos, null, null, subject, content, imageMap, isHtml, files);
+    }
+
+    /**
+     * 浣跨敤閰嶇疆鏂囦欢涓缃殑璐︽埛鍙戦�侀偖浠讹紝鍙戦�佺粰澶氫汉
+     *
+     * @param tos      鏀朵欢浜哄垪琛�
+     * @param ccs      鎶勯�佷汉鍒楄〃锛屽彲浠ヤ负null鎴栫┖
+     * @param bccs     瀵嗛�佷汉鍒楄〃锛屽彲浠ヤ负null鎴栫┖
+     * @param subject  鏍囬
+     * @param content  姝f枃
+     * @param imageMap 鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:$IMAGE_PLACEHOLDER
+     * @param isHtml   鏄惁涓篐TML
+     * @param files    闄勪欢鍒楄〃
+     * @return message-id
+     * @since 4.0.3
+     */
+    public static String send(Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) {
+        return send(getMailAccount(), true, tos, ccs, bccs, subject, content, imageMap, isHtml, files);
+    }
+
+    // ------------------------------------------------------------------------------------------------------------------------------- Custom MailAccount
+
+    /**
+     * 鍙戦�侀偖浠剁粰澶氫汉
+     *
+     * @param mailAccount 閭欢璁よ瘉瀵硅薄
+     * @param to          鏀朵欢浜猴紝澶氫釜鏀朵欢浜洪�楀彿鎴栬�呭垎鍙烽殧寮�
+     * @param subject     鏍囬
+     * @param content     姝f枃
+     * @param imageMap    鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:$IMAGE_PLACEHOLDER
+     * @param isHtml      鏄惁涓篐TML鏍煎紡
+     * @param files       闄勪欢鍒楄〃
+     * @return message-id
+     * @since 3.2.0
+     */
+    public static String send(MailAccount mailAccount, String to, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) {
+        return send(mailAccount, splitAddress(to), subject, content, imageMap, isHtml, files);
+    }
+
+    /**
+     * 鍙戦�侀偖浠剁粰澶氫汉
+     *
+     * @param mailAccount 閭欢甯愭埛淇℃伅
+     * @param tos         鏀朵欢浜哄垪琛�
+     * @param subject     鏍囬
+     * @param content     姝f枃
+     * @param imageMap    鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:$IMAGE_PLACEHOLDER
+     * @param isHtml      鏄惁涓篐TML鏍煎紡
+     * @param files       闄勪欢鍒楄〃
+     * @return message-id
+     * @since 4.6.3
+     */
+    public static String send(MailAccount mailAccount, Collection<String> tos, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) {
+        return send(mailAccount, tos, null, null, subject, content, imageMap, isHtml, files);
+    }
+
+    /**
+     * 鍙戦�侀偖浠剁粰澶氫汉
+     *
+     * @param mailAccount 閭欢甯愭埛淇℃伅
+     * @param tos         鏀朵欢浜哄垪琛�
+     * @param ccs         鎶勯�佷汉鍒楄〃锛屽彲浠ヤ负null鎴栫┖
+     * @param bccs        瀵嗛�佷汉鍒楄〃锛屽彲浠ヤ负null鎴栫┖
+     * @param subject     鏍囬
+     * @param content     姝f枃
+     * @param imageMap    鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:$IMAGE_PLACEHOLDER
+     * @param isHtml      鏄惁涓篐TML鏍煎紡
+     * @param files       闄勪欢鍒楄〃
+     * @return message-id
+     * @since 4.6.3
+     */
+    public static String send(MailAccount mailAccount, Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content, Map<String, InputStream> imageMap,
+                              boolean isHtml, File... files) {
+        return send(mailAccount, false, tos, ccs, bccs, subject, content, imageMap, isHtml, files);
+    }
+
+    /**
+     * 鏍规嵁閰嶇疆鏂囦欢锛岃幏鍙栭偖浠跺鎴风浼氳瘽
+     *
+     * @param mailAccount 閭欢璐︽埛閰嶇疆
+     * @param isSingleton 鏄惁鍗曚緥锛堝叏灞�鍏变韩浼氳瘽锛�
+     * @return {@link Session}
+     * @since 5.5.7
+     */
+    public static Session getSession(MailAccount mailAccount, boolean isSingleton) {
+        Authenticator authenticator = null;
+        if (mailAccount.isAuth()) {
+            authenticator = new UserPassAuthenticator(mailAccount.getUser(), mailAccount.getPass());
+        }
+
+        return isSingleton ? Session.getDefaultInstance(mailAccount.getSmtpProps(), authenticator) //
+            : Session.getInstance(mailAccount.getSmtpProps(), authenticator);
+    }
+
+    // ------------------------------------------------------------------------------------------------------------------------ Private method start
+
+    /**
+     * 鍙戦�侀偖浠剁粰澶氫汉
+     *
+     * @param mailAccount      閭欢甯愭埛淇℃伅
+     * @param useGlobalSession 鏄惁鍏ㄥ眬鍏变韩Session
+     * @param tos              鏀朵欢浜哄垪琛�
+     * @param ccs              鎶勯�佷汉鍒楄〃锛屽彲浠ヤ负null鎴栫┖
+     * @param bccs             瀵嗛�佷汉鍒楄〃锛屽彲浠ヤ负null鎴栫┖
+     * @param subject          鏍囬
+     * @param content          姝f枃
+     * @param imageMap         鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:${cid}
+     * @param isHtml           鏄惁涓篐TML鏍煎紡
+     * @param files            闄勪欢鍒楄〃
+     * @return message-id
+     * @since 4.6.3
+     */
+    private static String send(MailAccount mailAccount, boolean useGlobalSession, Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content,
+                               Map<String, InputStream> imageMap, boolean isHtml, File... files) {
+        final org.dromara.common.mail.utils.Mail mail = Mail.create(mailAccount).setUseGlobalSession(useGlobalSession);
+
+        // 鍙�夋妱閫佷汉
+        if (CollUtil.isNotEmpty(ccs)) {
+            mail.setCcs(ccs.toArray(new String[0]));
+        }
+        // 鍙�夊瘑閫佷汉
+        if (CollUtil.isNotEmpty(bccs)) {
+            mail.setBccs(bccs.toArray(new String[0]));
+        }
+
+        mail.setTos(tos.toArray(new String[0]));
+        mail.setTitle(subject);
+        mail.setContent(content);
+        mail.setHtml(isHtml);
+        mail.setFiles(files);
+
+        // 鍥剧墖
+        if (MapUtil.isNotEmpty(imageMap)) {
+            for (Map.Entry<String, InputStream> entry : imageMap.entrySet()) {
+                mail.addImage(entry.getKey(), entry.getValue());
+                // 鍏抽棴娴�
+                IoUtil.close(entry.getValue());
+            }
+        }
+
+        return mail.send();
+    }
+
+    /**
+     * 灏嗗涓仈绯讳汉杞负鍒楄〃锛屽垎闅旂涓洪�楀彿鎴栬�呭垎鍙�
+     *
+     * @param addresses 澶氫釜鑱旂郴浜猴紝濡傛灉涓虹┖杩斿洖null
+     * @return 鑱旂郴浜哄垪琛�
+     */
+    private static List<String> splitAddress(String addresses) {
+        if (StrUtil.isBlank(addresses)) {
+            return null;
+        }
+
+        List<String> result;
+        if (StrUtil.contains(addresses, CharUtil.COMMA)) {
+            result = StrUtil.splitTrim(addresses, CharUtil.COMMA);
+        } else if (StrUtil.contains(addresses, ';')) {
+            result = StrUtil.splitTrim(addresses, ';');
+        } else {
+            result = CollUtil.newArrayList(addresses);
+        }
+        return result;
+    }
+    // ------------------------------------------------------------------------------------------------------------------------ Private method end
+
+}
diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/UserPassAuthenticator.java b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/UserPassAuthenticator.java
new file mode 100644
index 0000000..52ebd78
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/UserPassAuthenticator.java
@@ -0,0 +1,33 @@
+package org.dromara.common.mail.utils;
+
+import jakarta.mail.Authenticator;
+import jakarta.mail.PasswordAuthentication;
+
+/**
+ * 鐢ㄦ埛鍚嶅瘑鐮侀獙璇佸櫒
+ *
+ * @author looly
+ * @since 3.1.2
+ */
+public class UserPassAuthenticator extends Authenticator {
+
+	private final String user;
+	private final String pass;
+
+	/**
+	 * 鏋勯��
+	 *
+	 * @param user 鐢ㄦ埛鍚�
+	 * @param pass 瀵嗙爜
+	 */
+	public UserPassAuthenticator(String user, String pass) {
+		this.user = user;
+		this.pass = pass;
+	}
+
+	@Override
+	protected PasswordAuthentication getPasswordAuthentication() {
+		return new PasswordAuthentication(this.user, this.pass);
+	}
+
+}
diff --git a/ruoyi-common/ruoyi-common-mail/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-mail/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index f067b8b..ef0cf11 100644
--- a/ruoyi-common/ruoyi-common-mail/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-common/ruoyi-common-mail/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +1 @@
-com.ruoyi.common.mail.config.MailConfig
+org.dromara.common.mail.config.MailConfig
diff --git a/ruoyi-common/ruoyi-common-mybatis/pom.xml b/ruoyi-common/ruoyi-common-mybatis/pom.xml
index 67e381f..5a003dc 100644
--- a/ruoyi-common/ruoyi-common-mybatis/pom.xml
+++ b/ruoyi-common/ruoyi-common-mybatis/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-common</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -18,12 +18,12 @@
 
     <dependencies>
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-core</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-satoken</artifactId>
         </dependency>
 
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/annotation/DataColumn.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/annotation/DataColumn.java
deleted file mode 100644
index bf703a2..0000000
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/annotation/DataColumn.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.ruoyi.common.mybatis.annotation;
-
-import java.lang.annotation.*;
-
-/**
- * 鏁版嵁鏉冮檺
- *
- * 涓�涓敞瑙e彧鑳藉搴斾竴涓ā鏉�
- *
- * @author Lion Li
- * @version 3.5.0
- */
-@Target(ElementType.METHOD)
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-public @interface DataColumn {
-
-    /**
-     * 鍗犱綅绗﹀叧閿瓧
-     */
-    String[] key() default "deptName";
-
-    /**
-     * 鍗犱綅绗︽浛鎹㈠��
-     */
-    String[] value() default "dept_id";
-
-}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/annotation/DataPermission.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/annotation/DataPermission.java
deleted file mode 100644
index 288c195..0000000
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/annotation/DataPermission.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.ruoyi.common.mybatis.annotation;
-
-import java.lang.annotation.*;
-
-/**
- * 鏁版嵁鏉冮檺缁�
- *
- * @author Lion Li
- * @version 3.5.0
- */
-@Target({ElementType.METHOD, ElementType.TYPE})
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-public @interface DataPermission {
-
-    DataColumn[] value();
-
-}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/config/MybatisPlusConfig.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/config/MybatisPlusConfig.java
deleted file mode 100644
index 7b824f1..0000000
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/config/MybatisPlusConfig.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package com.ruoyi.common.mybatis.config;
-
-import cn.hutool.core.net.NetUtil;
-import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
-import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator;
-import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
-import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
-import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
-import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
-import com.ruoyi.common.mybatis.handler.InjectionMetaObjectHandler;
-import com.ruoyi.common.mybatis.interceptor.PlusDataPermissionInterceptor;
-import org.mybatis.spring.annotation.MapperScan;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.context.annotation.Bean;
-import org.springframework.transaction.annotation.EnableTransactionManagement;
-
-/**
- * mybatis-plus閰嶇疆绫�(涓嬫柟娉ㄩ噴鏈夋彃浠朵粙缁�)
- *
- * @author Lion Li
- */
-@EnableTransactionManagement(proxyTargetClass = true)
-@AutoConfiguration
-@MapperScan("${mybatis-plus.mapperPackage}")
-public class MybatisPlusConfig {
-
-    @Bean
-    public MybatisPlusInterceptor mybatisPlusInterceptor() {
-        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
-        // 鏁版嵁鏉冮檺澶勭悊
-        interceptor.addInnerInterceptor(dataPermissionInterceptor());
-        // 鍒嗛〉鎻掍欢
-        interceptor.addInnerInterceptor(paginationInnerInterceptor());
-        // 涔愯閿佹彃浠�
-        interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor());
-        return interceptor;
-    }
-
-    /**
-     * 鏁版嵁鏉冮檺鎷︽埅鍣�
-     */
-    public PlusDataPermissionInterceptor dataPermissionInterceptor() {
-        return new PlusDataPermissionInterceptor();
-    }
-
-    /**
-     * 鍒嗛〉鎻掍欢锛岃嚜鍔ㄨ瘑鍒暟鎹簱绫诲瀷
-     */
-    public PaginationInnerInterceptor paginationInnerInterceptor() {
-        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
-        // 璁剧疆鏈�澶у崟椤甸檺鍒舵暟閲忥紝榛樿 500 鏉★紝-1 涓嶅彈闄愬埗
-        paginationInnerInterceptor.setMaxLimit(-1L);
-        // 鍒嗛〉鍚堢悊鍖�
-        paginationInnerInterceptor.setOverflow(true);
-        return paginationInnerInterceptor;
-    }
-
-    /**
-     * 涔愯閿佹彃浠�
-     */
-    public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor() {
-        return new OptimisticLockerInnerInterceptor();
-    }
-
-    /**
-     * 鍏冨璞″瓧娈靛~鍏呮帶鍒跺櫒
-     */
-    @Bean
-    public MetaObjectHandler metaObjectHandler() {
-        return new InjectionMetaObjectHandler();
-    }
-
-    /**
-     * 浣跨敤缃戝崱淇℃伅缁戝畾闆姳鐢熸垚鍣�
-     * 闃叉闆嗙兢闆姳ID閲嶅
-     */
-    @Bean
-    public IdentifierGenerator idGenerator() {
-        return new DefaultIdentifierGenerator(NetUtil.getLocalhost());
-    }
-
-    /**
-     * PaginationInnerInterceptor 鍒嗛〉鎻掍欢锛岃嚜鍔ㄨ瘑鍒暟鎹簱绫诲瀷
-     * https://baomidou.com/pages/97710a/
-     * OptimisticLockerInnerInterceptor 涔愯閿佹彃浠�
-     * https://baomidou.com/pages/0d93c0/
-     * MetaObjectHandler 鍏冨璞″瓧娈靛~鍏呮帶鍒跺櫒
-     * https://baomidou.com/pages/4c6bcf/
-     * ISqlInjector sql娉ㄥ叆鍣�
-     * https://baomidou.com/pages/42ea4a/
-     * BlockAttackInnerInterceptor 濡傛灉鏄鍏ㄨ〃鐨勫垹闄ゆ垨鏇存柊鎿嶄綔锛屽氨浼氱粓姝㈣鎿嶄綔
-     * https://baomidou.com/pages/f9a237/
-     * IllegalSQLInnerInterceptor sql鎬ц兘瑙勮寖鎻掍欢(鍨冨溇SQL鎷︽埅)
-     * IdentifierGenerator 鑷畾涔変富閿瓥鐣�
-     * https://baomidou.com/pages/568eb2/
-     * TenantLineInnerInterceptor 澶氱鎴锋彃浠�
-     * https://baomidou.com/pages/aef2f2/
-     * DynamicTableNameInnerInterceptor 鍔ㄦ�佽〃鍚嶆彃浠�
-     * https://baomidou.com/pages/2a45ff/
-     */
-
-}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/core/domain/BaseEntity.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/core/domain/BaseEntity.java
deleted file mode 100644
index 36d687e..0000000
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/core/domain/BaseEntity.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package com.ruoyi.common.mybatis.core.domain;
-
-import com.baomidou.mybatisplus.annotation.FieldFill;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Entity鍩虹被
- *
- * @author Lion Li
- */
-
-@Data
-public class BaseEntity implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 鎼滅储鍊�
-     */
-    @JsonIgnore
-    @TableField(exist = false)
-    private String searchValue;
-
-    /**
-     * 鍒涘缓閮ㄩ棬
-     */
-    @TableField(fill = FieldFill.INSERT)
-    private Long createDept;
-
-    /**
-     * 鍒涘缓鑰�
-     */
-    @TableField(fill = FieldFill.INSERT)
-    private Long createBy;
-
-    /**
-     * 鍒涘缓鏃堕棿
-     */
-    @TableField(fill = FieldFill.INSERT)
-    private Date createTime;
-
-    /**
-     * 鏇存柊鑰�
-     */
-    @TableField(fill = FieldFill.INSERT_UPDATE)
-    private Long updateBy;
-
-    /**
-     * 鏇存柊鏃堕棿
-     */
-    @TableField(fill = FieldFill.INSERT_UPDATE)
-    private Date updateTime;
-
-    /**
-     * 璇锋眰鍙傛暟
-     */
-    @JsonInclude(JsonInclude.Include.NON_EMPTY)
-    @TableField(exist = false)
-    private Map<String, Object> params = new HashMap<>();
-
-}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/core/mapper/BaseMapperPlus.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/core/mapper/BaseMapperPlus.java
deleted file mode 100644
index cbfe5cb..0000000
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/core/mapper/BaseMapperPlus.java
+++ /dev/null
@@ -1,198 +0,0 @@
-package com.ruoyi.common.mybatis.core.mapper;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.ObjectUtil;
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.baomidou.mybatisplus.extension.toolkit.Db;
-import com.ruoyi.common.core.utils.MapstructUtils;
-import org.apache.ibatis.logging.Log;
-import org.apache.ibatis.logging.LogFactory;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-/**
- * 鑷畾涔� Mapper 鎺ュ彛, 瀹炵幇 鑷畾涔夋墿灞�
- *
- * @param <T> table 娉涘瀷
- * @param <V> vo 娉涘瀷
- * @author Lion Li
- * @since 2021-05-13
- */
-@SuppressWarnings("unchecked")
-public interface BaseMapperPlus<T, V> extends BaseMapper<T> {
-
-    Log log = LogFactory.getLog(BaseMapperPlus.class);
-
-    default Class<V> currentVoClass() {
-        return (Class<V>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseMapperPlus.class, 1);
-    }
-
-    default Class<T> currentModelClass() {
-        return (Class<T>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseMapperPlus.class, 0);
-    }
-
-    default List<T> selectList() {
-        return this.selectList(new QueryWrapper<>());
-    }
-
-    /**
-     * 鎵归噺鎻掑叆
-     */
-    default boolean insertBatch(Collection<T> entityList) {
-        return Db.saveBatch(entityList);
-    }
-
-    /**
-     * 鎵归噺鏇存柊
-     */
-    default boolean updateBatchById(Collection<T> entityList) {
-        return Db.updateBatchById(entityList);
-    }
-
-    /**
-     * 鎵归噺鎻掑叆鎴栨洿鏂�
-     */
-    default boolean insertOrUpdateBatch(Collection<T> entityList) {
-        return Db.saveOrUpdateBatch(entityList);
-    }
-
-    /**
-     * 鎵归噺鎻掑叆(鍖呭惈闄愬埗鏉℃暟)
-     */
-    default boolean insertBatch(Collection<T> entityList, int batchSize) {
-        return Db.saveBatch(entityList, batchSize);
-    }
-
-    /**
-     * 鎵归噺鏇存柊(鍖呭惈闄愬埗鏉℃暟)
-     */
-    default boolean updateBatchById(Collection<T> entityList, int batchSize) {
-        return Db.updateBatchById(entityList, batchSize);
-    }
-
-    /**
-     * 鎵归噺鎻掑叆鎴栨洿鏂�(鍖呭惈闄愬埗鏉℃暟)
-     */
-    default boolean insertOrUpdateBatch(Collection<T> entityList, int batchSize) {
-        return Db.saveOrUpdateBatch(entityList, batchSize);
-    }
-
-    /**
-     * 鎻掑叆鎴栨洿鏂�(鍖呭惈闄愬埗鏉℃暟)
-     */
-    default boolean insertOrUpdate(T entity) {
-        return Db.saveOrUpdate(entity);
-    }
-
-    default V selectVoById(Serializable id) {
-        return selectVoById(id, this.currentVoClass());
-    }
-
-    /**
-     * 鏍规嵁 ID 鏌ヨ
-     */
-    default <C> C selectVoById(Serializable id, Class<C> voClass) {
-        T obj = this.selectById(id);
-        if (ObjectUtil.isNull(obj)) {
-            return null;
-        }
-        return MapstructUtils.convert(obj, voClass);
-    }
-
-    default List<V> selectVoBatchIds(Collection<? extends Serializable> idList) {
-        return selectVoBatchIds(idList, this.currentVoClass());
-    }
-
-    /**
-     * 鏌ヨ锛堟牴鎹甀D 鎵归噺鏌ヨ锛�
-     */
-    default <C> List<C> selectVoBatchIds(Collection<? extends Serializable> idList, Class<C> voClass) {
-        List<T> list = this.selectBatchIds(idList);
-        if (CollUtil.isEmpty(list)) {
-            return CollUtil.newArrayList();
-        }
-        return MapstructUtils.convert(list, voClass);
-    }
-
-    default List<V> selectVoByMap(Map<String, Object> map) {
-        return selectVoByMap(map, this.currentVoClass());
-    }
-
-    /**
-     * 鏌ヨ锛堟牴鎹� columnMap 鏉′欢锛�
-     */
-    default <C> List<C> selectVoByMap(Map<String, Object> map, Class<C> voClass) {
-        List<T> list = this.selectByMap(map);
-        if (CollUtil.isEmpty(list)) {
-            return CollUtil.newArrayList();
-        }
-        return MapstructUtils.convert(list, voClass);
-    }
-
-    default V selectVoOne(Wrapper<T> wrapper) {
-        return selectVoOne(wrapper, this.currentVoClass());
-    }
-
-    /**
-     * 鏍规嵁 entity 鏉′欢锛屾煡璇竴鏉¤褰�
-     */
-    default <C> C selectVoOne(Wrapper<T> wrapper, Class<C> voClass) {
-        T obj = this.selectOne(wrapper);
-        if (ObjectUtil.isNull(obj)) {
-            return null;
-        }
-        return MapstructUtils.convert(obj, voClass);
-    }
-
-    default List<V> selectVoList() {
-        return selectVoList(new QueryWrapper<>(), this.currentVoClass());
-    }
-
-    default List<V> selectVoList(Wrapper<T> wrapper) {
-        return selectVoList(wrapper, this.currentVoClass());
-    }
-
-    /**
-     * 鏍规嵁 entity 鏉′欢锛屾煡璇㈠叏閮ㄨ褰�
-     */
-    default <C> List<C> selectVoList(Wrapper<T> wrapper, Class<C> voClass) {
-        List<T> list = this.selectList(wrapper);
-        if (CollUtil.isEmpty(list)) {
-            return CollUtil.newArrayList();
-        }
-        return MapstructUtils.convert(list, voClass);
-    }
-
-    default <P extends IPage<V>> P selectVoPage(IPage<T> page, Wrapper<T> wrapper) {
-        return selectVoPage(page, wrapper, this.currentVoClass());
-    }
-
-    /**
-     * 鍒嗛〉鏌ヨVO
-     */
-    default <C, P extends IPage<C>> P selectVoPage(IPage<T> page, Wrapper<T> wrapper, Class<C> voClass) {
-        IPage<T> pageData = this.selectPage(page, wrapper);
-        IPage<C> voPage = new Page<>(pageData.getCurrent(), pageData.getSize(), pageData.getTotal());
-        if (CollUtil.isEmpty(pageData.getRecords())) {
-            return (P) voPage;
-        }
-        voPage.setRecords(MapstructUtils.convert(pageData.getRecords(), voClass));
-        return (P) voPage;
-    }
-
-    default <C> List<C> selectObjs(Wrapper<T> wrapper, Function<? super Object, C> mapper) {
-        return this.selectObjs(wrapper).stream().filter(Objects::nonNull).map(mapper).collect(Collectors.toList());
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/core/page/PageQuery.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/core/page/PageQuery.java
deleted file mode 100644
index d4c2432..0000000
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/core/page/PageQuery.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package com.ruoyi.common.mybatis.core.page;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.ObjectUtil;
-import com.baomidou.mybatisplus.core.metadata.OrderItem;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.core.utils.sql.SqlUtil;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * 鍒嗛〉鏌ヨ瀹炰綋绫�
- *
- * @author Lion Li
- */
-
-@Data
-public class PageQuery implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 鍒嗛〉澶у皬
-     */
-    private Integer pageSize;
-
-    /**
-     * 褰撳墠椤垫暟
-     */
-    private Integer pageNum;
-
-    /**
-     * 鎺掑簭鍒�
-     */
-    private String orderByColumn;
-
-    /**
-     * 鎺掑簭鐨勬柟鍚慸esc鎴栬�卆sc
-     */
-    private String isAsc;
-
-    /**
-     * 褰撳墠璁板綍璧峰绱㈠紩 榛樿鍊�
-     */
-    public static final int DEFAULT_PAGE_NUM = 1;
-
-    /**
-     * 姣忛〉鏄剧ず璁板綍鏁� 榛樿鍊� 榛樿鏌ュ叏閮�
-     */
-    public static final int DEFAULT_PAGE_SIZE = Integer.MAX_VALUE;
-
-    public <T> Page<T> build() {
-        Integer pageNum = ObjectUtil.defaultIfNull(getPageNum(), DEFAULT_PAGE_NUM);
-        Integer pageSize = ObjectUtil.defaultIfNull(getPageSize(), DEFAULT_PAGE_SIZE);
-        if (pageNum <= 0) {
-            pageNum = DEFAULT_PAGE_NUM;
-        }
-        Page<T> page = new Page<>(pageNum, pageSize);
-        List<OrderItem> orderItems = buildOrderItem();
-        if (CollUtil.isNotEmpty(orderItems)) {
-            page.addOrder(orderItems);
-        }
-        return page;
-    }
-
-    /**
-     * 鏋勫缓鎺掑簭
-     *
-     * 鏀寔鐨勭敤娉曞涓�:
-     * {isAsc:"asc",orderByColumn:"id"} order by id asc
-     * {isAsc:"asc",orderByColumn:"id,createTime"} order by id asc,create_time asc
-     * {isAsc:"desc",orderByColumn:"id,createTime"} order by id desc,create_time desc
-     * {isAsc:"asc,desc",orderByColumn:"id,createTime"} order by id asc,create_time desc
-     */
-    private List<OrderItem> buildOrderItem() {
-        if (StringUtils.isBlank(orderByColumn) || StringUtils.isBlank(isAsc)) {
-            return null;
-        }
-        String orderBy = SqlUtil.escapeOrderBySql(orderByColumn);
-        orderBy = StringUtils.toUnderScoreCase(orderBy);
-
-        // 鍏煎鍓嶇鎺掑簭绫诲瀷
-        isAsc = StringUtils.replaceEach(isAsc, new String[]{"ascending", "descending"}, new String[]{"asc", "desc"});
-
-        String[] orderByArr = orderBy.split(StringUtils.SEPARATOR);
-        String[] isAscArr = isAsc.split(StringUtils.SEPARATOR);
-        if (isAscArr.length != 1 && isAscArr.length != orderByArr.length) {
-            throw new ServiceException("鎺掑簭鍙傛暟鏈夎");
-        }
-
-        List<OrderItem> list = new ArrayList<>();
-        // 姣忎釜瀛楁鍚勮嚜鎺掑簭
-        for (int i = 0; i < orderByArr.length; i++) {
-            String orderByStr = orderByArr[i];
-            String isAscStr = isAscArr.length == 1 ? isAscArr[0] : isAscArr[i];
-            if ("asc".equals(isAscStr)) {
-                list.add(OrderItem.asc(orderByStr));
-            } else if ("desc".equals(isAscStr)) {
-                list.add(OrderItem.desc(orderByStr));
-            } else {
-                throw new ServiceException("鎺掑簭鍙傛暟鏈夎");
-            }
-        }
-        return list;
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/core/page/TableDataInfo.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/core/page/TableDataInfo.java
deleted file mode 100644
index feaf03f..0000000
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/core/page/TableDataInfo.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package com.ruoyi.common.mybatis.core.page;
-
-import cn.hutool.http.HttpStatus;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * 琛ㄦ牸鍒嗛〉鏁版嵁瀵硅薄
- *
- * @author Lion Li
- */
-
-@Data
-@NoArgsConstructor
-public class TableDataInfo<T> implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 鎬昏褰曟暟
-     */
-    private long total;
-
-    /**
-     * 鍒楄〃鏁版嵁
-     */
-    private List<T> rows;
-
-    /**
-     * 娑堟伅鐘舵�佺爜
-     */
-    private int code;
-
-    /**
-     * 娑堟伅鍐呭
-     */
-    private String msg;
-
-    /**
-     * 鍒嗛〉
-     *
-     * @param list  鍒楄〃鏁版嵁
-     * @param total 鎬昏褰曟暟
-     */
-    public TableDataInfo(List<T> list, long total) {
-        this.rows = list;
-        this.total = total;
-    }
-
-    public static <T> TableDataInfo<T> build(IPage<T> page) {
-        TableDataInfo<T> rspData = new TableDataInfo<>();
-        rspData.setCode(HttpStatus.HTTP_OK);
-        rspData.setMsg("鏌ヨ鎴愬姛");
-        rspData.setRows(page.getRecords());
-        rspData.setTotal(page.getTotal());
-        return rspData;
-    }
-
-    public static <T> TableDataInfo<T> build(List<T> list) {
-        TableDataInfo<T> rspData = new TableDataInfo<>();
-        rspData.setCode(HttpStatus.HTTP_OK);
-        rspData.setMsg("鏌ヨ鎴愬姛");
-        rspData.setRows(list);
-        rspData.setTotal(list.size());
-        return rspData;
-    }
-
-    public static <T> TableDataInfo<T> build() {
-        TableDataInfo<T> rspData = new TableDataInfo<>();
-        rspData.setCode(HttpStatus.HTTP_OK);
-        rspData.setMsg("鏌ヨ鎴愬姛");
-        return rspData;
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/enums/DataBaseType.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/enums/DataBaseType.java
deleted file mode 100644
index b50667e..0000000
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/enums/DataBaseType.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.ruoyi.common.mybatis.enums;
-
-import com.ruoyi.common.core.utils.StringUtils;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 鏁版嵁搴撶被鍨�
- *
- * @author Lion Li
- */
-@Getter
-@AllArgsConstructor
-public enum DataBaseType {
-
-    /**
-     * MySQL
-     */
-    MY_SQL("MySQL"),
-
-    /**
-     * Oracle
-     */
-    ORACLE("Oracle"),
-
-    /**
-     * PostgreSQL
-     */
-    POSTGRE_SQL("PostgreSQL"),
-
-    /**
-     * SQL Server
-     */
-    SQL_SERVER("Microsoft SQL Server");
-
-    private final String type;
-
-    public static DataBaseType find(String databaseProductName) {
-        if (StringUtils.isBlank(databaseProductName)) {
-            return null;
-        }
-        for (DataBaseType type : values()) {
-            if (type.getType().equals(databaseProductName)) {
-                return type;
-            }
-        }
-        return null;
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/enums/DataScopeType.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/enums/DataScopeType.java
deleted file mode 100644
index 0abb3b2..0000000
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/enums/DataScopeType.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package com.ruoyi.common.mybatis.enums;
-
-import com.ruoyi.common.core.utils.StringUtils;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 鏁版嵁鏉冮檺绫诲瀷
- * <p>
- * 璇硶鏀寔 spel 妯℃澘琛ㄨ揪寮�
- * <p>
- * 鍐呯疆鏁版嵁 user 褰撳墠鐢ㄦ埛 鍐呭鍙傝�� LoginUser
- * 濡傞渶鎵╁睍鏁版嵁 鍙娇鐢� {@link com.ruoyi.common.mybatis.helper.DataPermissionHelper} 鎿嶄綔
- * 鍐呯疆鏈嶅姟 sdss 绯荤粺鏁版嵁鏉冮檺鏈嶅姟 鍐呭鍙傝�� SysDataScopeService
- * 濡傞渶鎵╁睍鏇村鑷畾涔夋湇鍔� 鍙互鍙傝�� sdss 鑷缂栧啓
- *
- * @author Lion Li
- * @version 3.5.0
- */
-@Getter
-@AllArgsConstructor
-public enum DataScopeType {
-
-    /**
-     * 鍏ㄩ儴鏁版嵁鏉冮檺
-     */
-    ALL("1", "", ""),
-
-    /**
-     * 鑷畾鏁版嵁鏉冮檺
-     */
-    CUSTOM("2", " #{#deptName} IN ( #{@sdss.getRoleCustom( #user.roleId )} ) ", ""),
-
-    /**
-     * 閮ㄩ棬鏁版嵁鏉冮檺
-     */
-    DEPT("3", " #{#deptName} = #{#user.deptId} ", ""),
-
-    /**
-     * 閮ㄩ棬鍙婁互涓嬫暟鎹潈闄�
-     */
-    DEPT_AND_CHILD("4", " #{#deptName} IN ( #{@sdss.getDeptAndChild( #user.deptId )} )", ""),
-
-    /**
-     * 浠呮湰浜烘暟鎹潈闄�
-     */
-    SELF("5", " #{#userName} = #{#user.userId} ", " 1 = 0 ");
-
-    private final String code;
-
-    /**
-     * 璇硶 閲囩敤 spel 妯℃澘琛ㄨ揪寮�
-     */
-    private final String sqlTemplate;
-
-    /**
-     * 涓嶆弧瓒� sqlTemplate 鍒欏~鍏�
-     */
-    private final String elseSql;
-
-    public static DataScopeType findCode(String code) {
-        if (StringUtils.isBlank(code)) {
-            return null;
-        }
-        for (DataScopeType type : values()) {
-            if (type.getCode().equals(code)) {
-                return type;
-            }
-        }
-        return null;
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/handler/InjectionMetaObjectHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/handler/InjectionMetaObjectHandler.java
deleted file mode 100644
index 246e1de..0000000
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/handler/InjectionMetaObjectHandler.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package com.ruoyi.common.mybatis.handler;
-
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.http.HttpStatus;
-import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
-import com.ruoyi.common.core.domain.model.LoginUser;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-import com.ruoyi.common.satoken.utils.LoginHelper;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.ibatis.reflection.MetaObject;
-
-import java.util.Date;
-
-/**
- * MP娉ㄥ叆澶勭悊鍣�
- *
- * @author Lion Li
- * @date 2021/4/25
- */
-@Slf4j
-public class InjectionMetaObjectHandler implements MetaObjectHandler {
-
-    @Override
-    public void insertFill(MetaObject metaObject) {
-        try {
-            if (ObjectUtil.isNotNull(metaObject) && metaObject.getOriginalObject() instanceof BaseEntity baseEntity) {
-                Date current = ObjectUtil.isNotNull(baseEntity.getCreateTime())
-                    ? baseEntity.getCreateTime() : new Date();
-                baseEntity.setCreateTime(current);
-                baseEntity.setUpdateTime(current);
-                LoginUser loginUser = getLoginUser();
-                if (ObjectUtil.isNotNull(loginUser)) {
-                    Long userId = ObjectUtil.isNotNull(baseEntity.getCreateBy())
-                        ? baseEntity.getCreateBy() : loginUser.getUserId();
-                    // 褰撳墠宸茬櫥褰� 涓� 鍒涘缓浜轰负绌� 鍒欏~鍏�
-                    baseEntity.setCreateBy(userId);
-                    // 褰撳墠宸茬櫥褰� 涓� 鏇存柊浜轰负绌� 鍒欏~鍏�
-                    baseEntity.setUpdateBy(userId);
-                    baseEntity.setCreateDept(ObjectUtil.isNotNull(baseEntity.getCreateDept())
-                        ? baseEntity.getCreateDept() : loginUser.getDeptId());
-                }
-            }
-        } catch (Exception e) {
-            throw new ServiceException("鑷姩娉ㄥ叆寮傚父 => " + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED);
-        }
-    }
-
-    @Override
-    public void updateFill(MetaObject metaObject) {
-        try {
-            if (ObjectUtil.isNotNull(metaObject) && metaObject.getOriginalObject() instanceof BaseEntity baseEntity) {
-                Date current = new Date();
-                // 鏇存柊鏃堕棿濉厖(涓嶇涓轰笉涓虹┖)
-                baseEntity.setUpdateTime(current);
-                LoginUser loginUser = getLoginUser();
-                // 褰撳墠宸茬櫥褰� 鏇存柊浜哄~鍏�(涓嶇涓轰笉涓虹┖)
-                if (ObjectUtil.isNotNull(loginUser)) {
-                    baseEntity.setUpdateBy(loginUser.getUserId());
-                }
-            }
-        } catch (Exception e) {
-            throw new ServiceException("鑷姩娉ㄥ叆寮傚父 => " + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED);
-        }
-    }
-
-    /**
-     * 鑾峰彇鐧诲綍鐢ㄦ埛鍚�
-     */
-    private LoginUser getLoginUser() {
-        LoginUser loginUser;
-        try {
-            loginUser = LoginHelper.getLoginUser();
-        } catch (Exception e) {
-            log.warn("鑷姩娉ㄥ叆璀﹀憡 => 鐢ㄦ埛鏈櫥褰�");
-            return null;
-        }
-        return loginUser;
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/handler/MybatisExceptionHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/handler/MybatisExceptionHandler.java
deleted file mode 100644
index 12e1d0c..0000000
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/handler/MybatisExceptionHandler.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package com.ruoyi.common.mybatis.handler;
-
-import com.ruoyi.common.core.domain.R;
-import lombok.extern.slf4j.Slf4j;
-import org.mybatis.spring.MyBatisSystemException;
-import org.springframework.dao.DuplicateKeyException;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.bind.annotation.RestControllerAdvice;
-
-import jakarta.servlet.http.HttpServletRequest;
-
-/**
- * Mybatis寮傚父澶勭悊鍣�
- *
- * @author Lion Li
- */
-@Slf4j
-@RestControllerAdvice
-public class MybatisExceptionHandler {
-
-    /**
-     * 涓婚敭鎴朥NIQUE绱㈠紩锛屾暟鎹噸澶嶅紓甯�
-     */
-    @ExceptionHandler(DuplicateKeyException.class)
-    public R<Void> handleDuplicateKeyException(DuplicateKeyException e, HttpServletRequest request) {
-        String requestURI = request.getRequestURI();
-        log.error("璇锋眰鍦板潃'{}',鏁版嵁搴撲腑宸插瓨鍦ㄨ褰�'{}'", requestURI, e.getMessage());
-        return R.fail("鏁版嵁搴撲腑宸插瓨鍦ㄨ璁板綍锛岃鑱旂郴绠$悊鍛樼‘璁�");
-    }
-
-    /**
-     * Mybatis绯荤粺寮傚父 閫氱敤澶勭悊
-     */
-    @ExceptionHandler(MyBatisSystemException.class)
-    public R<Void> handleCannotFindDataSourceException(MyBatisSystemException e, HttpServletRequest request) {
-        String requestURI = request.getRequestURI();
-        String message = e.getMessage();
-        if (message.contains("CannotFindDataSourceException")) {
-            log.error("璇锋眰鍦板潃'{}', 鏈壘鍒版暟鎹簮", requestURI);
-            return R.fail("鏈壘鍒版暟鎹簮锛岃鑱旂郴绠$悊鍛樼‘璁�");
-        }
-        log.error("璇锋眰鍦板潃'{}', Mybatis绯荤粺寮傚父", requestURI, e);
-        return R.fail(message);
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/handler/PlusDataPermissionHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/handler/PlusDataPermissionHandler.java
deleted file mode 100644
index 6e238a8..0000000
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/handler/PlusDataPermissionHandler.java
+++ /dev/null
@@ -1,198 +0,0 @@
-package com.ruoyi.common.mybatis.handler;
-
-import cn.hutool.core.annotation.AnnotationUtil;
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.collection.ConcurrentHashSet;
-import cn.hutool.core.util.ArrayUtil;
-import cn.hutool.core.util.ClassUtil;
-import cn.hutool.core.util.ObjectUtil;
-import com.ruoyi.common.core.domain.dto.RoleDTO;
-import com.ruoyi.common.core.domain.model.LoginUser;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.utils.SpringUtils;
-import com.ruoyi.common.core.utils.StreamUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.mybatis.annotation.DataColumn;
-import com.ruoyi.common.mybatis.annotation.DataPermission;
-import com.ruoyi.common.mybatis.enums.DataScopeType;
-import com.ruoyi.common.mybatis.helper.DataPermissionHelper;
-import com.ruoyi.common.satoken.utils.LoginHelper;
-import lombok.extern.slf4j.Slf4j;
-import net.sf.jsqlparser.JSQLParserException;
-import net.sf.jsqlparser.expression.Expression;
-import net.sf.jsqlparser.expression.Parenthesis;
-import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
-import net.sf.jsqlparser.parser.CCJSqlParserUtil;
-import org.springframework.context.expression.BeanFactoryResolver;
-import org.springframework.expression.BeanResolver;
-import org.springframework.expression.ExpressionParser;
-import org.springframework.expression.ParserContext;
-import org.springframework.expression.common.TemplateParserContext;
-import org.springframework.expression.spel.standard.SpelExpressionParser;
-import org.springframework.expression.spel.support.StandardEvaluationContext;
-
-import java.lang.reflect.Method;
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Function;
-
-/**
- * 鏁版嵁鏉冮檺杩囨护
- *
- * @author Lion Li
- * @version 3.5.0
- */
-@Slf4j
-public class PlusDataPermissionHandler {
-
-    /**
-     * 鏂规硶鎴栫被(鍚嶇О) 涓� 娉ㄨВ鐨勬槧灏勫叧绯荤紦瀛�
-     */
-    private final Map<String, DataPermission> dataPermissionCacheMap = new ConcurrentHashMap<>();
-
-    /**
-     * 鏃犳晥娉ㄨВ鏂规硶缂撳瓨鐢ㄤ簬蹇�熻繑鍥�
-     */
-    private final Set<String> invalidCacheSet = new ConcurrentHashSet<>();
-
-    /**
-     * spel 瑙f瀽鍣�
-     */
-    private final ExpressionParser parser = new SpelExpressionParser();
-    private final ParserContext parserContext = new TemplateParserContext();
-    /**
-     * bean瑙f瀽鍣� 鐢ㄤ簬澶勭悊 spel 琛ㄨ揪寮忎腑瀵� bean 鐨勮皟鐢�
-     */
-    private final BeanResolver beanResolver = new BeanFactoryResolver(SpringUtils.getBeanFactory());
-
-
-    public Expression getSqlSegment(Expression where, String mappedStatementId, boolean isSelect) {
-        DataColumn[] dataColumns = findAnnotation(mappedStatementId);
-        if (ArrayUtil.isEmpty(dataColumns)) {
-            invalidCacheSet.add(mappedStatementId);
-            return where;
-        }
-        LoginUser currentUser = DataPermissionHelper.getVariable("user");
-        if (ObjectUtil.isNull(currentUser)) {
-            currentUser = LoginHelper.getLoginUser();
-            DataPermissionHelper.setVariable("user", currentUser);
-        }
-        // 濡傛灉鏄秴绾х鐞嗗憳鎴栫鎴风鐞嗗憳锛屽垯涓嶈繃婊ゆ暟鎹�
-        if (LoginHelper.isSuperAdmin() || LoginHelper.isTenantAdmin()) {
-            return where;
-        }
-        String dataFilterSql = buildDataFilter(dataColumns, isSelect);
-        if (StringUtils.isBlank(dataFilterSql)) {
-            return where;
-        }
-        try {
-            Expression expression = CCJSqlParserUtil.parseExpression(dataFilterSql);
-            // 鏁版嵁鏉冮檺浣跨敤鍗曠嫭鐨勬嫭鍙� 闃叉涓庡叾浠栨潯浠跺啿绐�
-            Parenthesis parenthesis = new Parenthesis(expression);
-            if (ObjectUtil.isNotNull(where)) {
-                return new AndExpression(where, parenthesis);
-            } else {
-                return parenthesis;
-            }
-        } catch (JSQLParserException e) {
-            throw new ServiceException("鏁版嵁鏉冮檺瑙f瀽寮傚父 => " + e.getMessage());
-        }
-    }
-
-    /**
-     * 鏋勯�犳暟鎹繃婊ql
-     */
-    private String buildDataFilter(DataColumn[] dataColumns, boolean isSelect) {
-        // 鏇存柊鎴栧垹闄ら渶婊¤冻鎵�鏈夋潯浠�
-        String joinStr = isSelect ? " OR " : " AND ";
-        LoginUser user = DataPermissionHelper.getVariable("user");
-        StandardEvaluationContext context = new StandardEvaluationContext();
-        context.setBeanResolver(beanResolver);
-        DataPermissionHelper.getContext().forEach(context::setVariable);
-        Set<String> conditions = new HashSet<>();
-        for (RoleDTO role : user.getRoles()) {
-            user.setRoleId(role.getRoleId());
-            // 鑾峰彇瑙掕壊鏉冮檺娉涘瀷
-            DataScopeType type = DataScopeType.findCode(role.getDataScope());
-            if (ObjectUtil.isNull(type)) {
-                throw new ServiceException("瑙掕壊鏁版嵁鑼冨洿寮傚父 => " + role.getDataScope());
-            }
-            // 鍏ㄩ儴鏁版嵁鏉冮檺鐩存帴杩斿洖
-            if (type == DataScopeType.ALL) {
-                return "";
-            }
-            boolean isSuccess = false;
-            for (DataColumn dataColumn : dataColumns) {
-                if (dataColumn.key().length != dataColumn.value().length) {
-                    throw new ServiceException("瑙掕壊鏁版嵁鑼冨洿寮傚父 => key涓巚alue闀垮害涓嶅尮閰�");
-                }
-                // 涓嶅寘鍚� key 鍙橀噺 鍒欎笉澶勭悊
-                if (!StringUtils.containsAny(type.getSqlTemplate(),
-                    Arrays.stream(dataColumn.key()).map(key -> "#" + key).toArray(String[]::new)
-                )) {
-                    continue;
-                }
-                // 璁剧疆娉ㄨВ鍙橀噺 key 涓鸿〃杈惧紡鍙橀噺 value 涓哄彉閲忓��
-                for (int i = 0; i < dataColumn.key().length; i++) {
-                    context.setVariable(dataColumn.key()[i], dataColumn.value()[i]);
-                }
-
-                // 瑙f瀽sql妯℃澘骞跺~鍏�
-                String sql = parser.parseExpression(type.getSqlTemplate(), parserContext).getValue(context, String.class);
-                conditions.add(joinStr + sql);
-                isSuccess = true;
-            }
-            // 鏈鐞嗘垚鍔熷垯濉厖鍏滃簳鏂规
-            if (!isSuccess && StringUtils.isNotBlank(type.getElseSql())) {
-                conditions.add(joinStr + type.getElseSql());
-            }
-        }
-
-        if (CollUtil.isNotEmpty(conditions)) {
-            String sql = StreamUtils.join(conditions, Function.identity(), "");
-            return sql.substring(joinStr.length());
-        }
-        return "";
-    }
-
-    private DataColumn[] findAnnotation(String mappedStatementId) {
-        StringBuilder sb = new StringBuilder(mappedStatementId);
-        int index = sb.lastIndexOf(".");
-        String clazzName = sb.substring(0, index);
-        String methodName = sb.substring(index + 1, sb.length());
-        Class<?> clazz = ClassUtil.loadClass(clazzName);
-        List<Method> methods = Arrays.stream(ClassUtil.getDeclaredMethods(clazz))
-            .filter(method -> method.getName().equals(methodName)).toList();
-        DataPermission dataPermission;
-        // 鑾峰彇鏂规硶娉ㄨВ
-        for (Method method : methods) {
-            dataPermission = dataPermissionCacheMap.get(mappedStatementId);
-            if (ObjectUtil.isNotNull(dataPermission)) {
-                return dataPermission.value();
-            }
-            if (AnnotationUtil.hasAnnotation(method, DataPermission.class)) {
-                dataPermission = AnnotationUtil.getAnnotation(method, DataPermission.class);
-                dataPermissionCacheMap.put(mappedStatementId, dataPermission);
-                return dataPermission.value();
-            }
-        }
-        dataPermission = dataPermissionCacheMap.get(clazz.getName());
-        if (ObjectUtil.isNotNull(dataPermission)) {
-            return dataPermission.value();
-        }
-        // 鑾峰彇绫绘敞瑙�
-        if (AnnotationUtil.hasAnnotation(clazz, DataPermission.class)) {
-            dataPermission = AnnotationUtil.getAnnotation(clazz, DataPermission.class);
-            dataPermissionCacheMap.put(clazz.getName(), dataPermission);
-            return dataPermission.value();
-        }
-        return null;
-    }
-
-    /**
-     * 鏄惁涓烘棤鏁堟柟娉� 鏃犳暟鎹潈闄�
-     */
-    public boolean isInvalid(String mappedStatementId) {
-        return invalidCacheSet.contains(mappedStatementId);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/helper/DataBaseHelper.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/helper/DataBaseHelper.java
deleted file mode 100644
index 7aad90b..0000000
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/helper/DataBaseHelper.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package com.ruoyi.common.mybatis.helper;
-
-import cn.hutool.core.convert.Convert;
-import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.utils.SpringUtils;
-import com.ruoyi.common.mybatis.enums.DataBaseType;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-
-import javax.sql.DataSource;
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.SQLException;
-
-/**
- * 鏁版嵁搴撳姪鎵�
- *
- * @author Lion Li
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class DataBaseHelper {
-
-    private static final DynamicRoutingDataSource DS = SpringUtils.getBean(DynamicRoutingDataSource.class);
-
-    /**
-     * 鑾峰彇褰撳墠鏁版嵁搴撶被鍨�
-     */
-    public static DataBaseType getDataBaseType() {
-        DataSource dataSource = DS.determineDataSource();
-        try (Connection conn = dataSource.getConnection()) {
-            DatabaseMetaData metaData = conn.getMetaData();
-            String databaseProductName = metaData.getDatabaseProductName();
-            return DataBaseType.find(databaseProductName);
-        } catch (SQLException e) {
-            throw new ServiceException(e.getMessage());
-        }
-    }
-
-    public static boolean isMySql() {
-        return DataBaseType.MY_SQL == getDataBaseType();
-    }
-
-    public static boolean isOracle() {
-        return DataBaseType.ORACLE == getDataBaseType();
-    }
-
-    public static boolean isPostgerSql() {
-        return DataBaseType.POSTGRE_SQL == getDataBaseType();
-    }
-
-    public static boolean isSqlServer() {
-        return DataBaseType.SQL_SERVER == getDataBaseType();
-    }
-
-    public static String findInSet(Object var1, String var2) {
-        DataBaseType dataBasyType = getDataBaseType();
-        String var = Convert.toStr(var1);
-        if (dataBasyType == DataBaseType.SQL_SERVER) {
-            // charindex(',100,' , ',0,100,101,') <> 0
-            return "charindex(',%s,' , ','+%s+',') <> 0".formatted(var, var2);
-        } else if (dataBasyType == DataBaseType.POSTGRE_SQL) {
-            // (select position(',100,' in ',0,100,101,')) <> 0
-            return "(select position(',%s,' in ','||%s||',')) <> 0".formatted(var, var2);
-        } else if (dataBasyType == DataBaseType.ORACLE) {
-            // instr(',0,100,101,' , ',100,') <> 0
-            return "instr(','||%s||',' , ',%s,') <> 0".formatted(var2, var);
-        }
-        // find_in_set(100 , '0,100,101')
-        return "find_in_set('%s' , %s) <> 0".formatted(var, var2);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/helper/DataPermissionHelper.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/helper/DataPermissionHelper.java
deleted file mode 100644
index 8423c1c..0000000
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/helper/DataPermissionHelper.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package com.ruoyi.common.mybatis.helper;
-
-import cn.dev33.satoken.context.SaHolder;
-import cn.dev33.satoken.context.model.SaStorage;
-import cn.hutool.core.util.ObjectUtil;
-import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy;
-import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * 鏁版嵁鏉冮檺鍔╂墜
- *
- * @author Lion Li
- * @version 3.5.0
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-@SuppressWarnings("unchecked cast")
-public class DataPermissionHelper {
-
-    private static final String DATA_PERMISSION_KEY = "data:permission";
-
-    public static <T> T getVariable(String key) {
-        Map<String, Object> context = getContext();
-        return (T) context.get(key);
-    }
-
-
-    public static void setVariable(String key, Object value) {
-        Map<String, Object> context = getContext();
-        context.put(key, value);
-    }
-
-    public static Map<String, Object> getContext() {
-        SaStorage saStorage = SaHolder.getStorage();
-        Object attribute = saStorage.get(DATA_PERMISSION_KEY);
-        if (ObjectUtil.isNull(attribute)) {
-            saStorage.set(DATA_PERMISSION_KEY, new HashMap<>());
-            attribute = saStorage.get(DATA_PERMISSION_KEY);
-        }
-        if (attribute instanceof Map map) {
-            return map;
-        }
-        throw new NullPointerException("data permission context type exception");
-    }
-
-    /**
-     * 寮�鍚拷鐣ユ暟鎹潈闄�(寮�鍚悗闇�鎵嬪姩璋冪敤 {@link #disableIgnore()} 鍏抽棴)
-     */
-    public static void enableIgnore() {
-        InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().dataPermission(true).build());
-    }
-
-    /**
-     * 鍏抽棴蹇界暐鏁版嵁鏉冮檺
-     */
-    public static void disableIgnore() {
-        InterceptorIgnoreHelper.clearIgnoreStrategy();
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/interceptor/PlusDataPermissionInterceptor.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/interceptor/PlusDataPermissionInterceptor.java
deleted file mode 100644
index fd4ffcd..0000000
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/interceptor/PlusDataPermissionInterceptor.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package com.ruoyi.common.mybatis.interceptor;
-
-import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
-import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
-import com.baomidou.mybatisplus.extension.parser.JsqlParserSupport;
-import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
-import com.ruoyi.common.mybatis.handler.PlusDataPermissionHandler;
-import net.sf.jsqlparser.expression.Expression;
-import net.sf.jsqlparser.statement.delete.Delete;
-import net.sf.jsqlparser.statement.select.PlainSelect;
-import net.sf.jsqlparser.statement.select.Select;
-import net.sf.jsqlparser.statement.select.SelectBody;
-import net.sf.jsqlparser.statement.select.SetOperationList;
-import net.sf.jsqlparser.statement.update.Update;
-import org.apache.ibatis.executor.Executor;
-import org.apache.ibatis.executor.statement.StatementHandler;
-import org.apache.ibatis.mapping.BoundSql;
-import org.apache.ibatis.mapping.MappedStatement;
-import org.apache.ibatis.mapping.SqlCommandType;
-import org.apache.ibatis.session.ResultHandler;
-import org.apache.ibatis.session.RowBounds;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.List;
-
-/**
- * 鏁版嵁鏉冮檺鎷︽埅鍣�
- *
- * @author Lion Li
- * @version 3.5.0
- */
-public class PlusDataPermissionInterceptor extends JsqlParserSupport implements InnerInterceptor {
-
-    private final PlusDataPermissionHandler dataPermissionHandler = new PlusDataPermissionHandler();
-
-    @Override
-    public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
-        // 妫�鏌ュ拷鐣ユ敞瑙�
-        if (InterceptorIgnoreHelper.willIgnoreDataPermission(ms.getId())) {
-            return;
-        }
-        // 妫�鏌ユ槸鍚︽棤鏁� 鏃犳暟鎹潈闄愭敞瑙�
-        if (dataPermissionHandler.isInvalid(ms.getId())) {
-            return;
-        }
-        // 瑙f瀽 sql 鍒嗛厤瀵瑰簲鏂规硶
-        PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
-        mpBs.sql(parserSingle(mpBs.sql(), ms.getId()));
-    }
-
-    @Override
-    public void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) {
-        PluginUtils.MPStatementHandler mpSh = PluginUtils.mpStatementHandler(sh);
-        MappedStatement ms = mpSh.mappedStatement();
-        SqlCommandType sct = ms.getSqlCommandType();
-        if (sct == SqlCommandType.UPDATE || sct == SqlCommandType.DELETE) {
-            if (InterceptorIgnoreHelper.willIgnoreDataPermission(ms.getId())) {
-                return;
-            }
-            PluginUtils.MPBoundSql mpBs = mpSh.mPBoundSql();
-            mpBs.sql(parserMulti(mpBs.sql(), ms.getId()));
-        }
-    }
-
-    @Override
-    protected void processSelect(Select select, int index, String sql, Object obj) {
-        SelectBody selectBody = select.getSelectBody();
-        if (selectBody instanceof PlainSelect) {
-            this.setWhere((PlainSelect) selectBody, (String) obj);
-        } else if (selectBody instanceof SetOperationList setOperationList) {
-            List<SelectBody> selectBodyList = setOperationList.getSelects();
-            selectBodyList.forEach(s -> this.setWhere((PlainSelect) s, (String) obj));
-        }
-    }
-
-    @Override
-    protected void processUpdate(Update update, int index, String sql, Object obj) {
-        Expression sqlSegment = dataPermissionHandler.getSqlSegment(update.getWhere(), (String) obj, false);
-        if (null != sqlSegment) {
-            update.setWhere(sqlSegment);
-        }
-    }
-
-    @Override
-    protected void processDelete(Delete delete, int index, String sql, Object obj) {
-        Expression sqlSegment = dataPermissionHandler.getSqlSegment(delete.getWhere(), (String) obj, false);
-        if (null != sqlSegment) {
-            delete.setWhere(sqlSegment);
-        }
-    }
-
-    /**
-     * 璁剧疆 where 鏉′欢
-     *
-     * @param plainSelect       鏌ヨ瀵硅薄
-     * @param mappedStatementId 鎵ц鏂规硶id
-     */
-    protected void setWhere(PlainSelect plainSelect, String mappedStatementId) {
-        Expression sqlSegment = dataPermissionHandler.getSqlSegment(plainSelect.getWhere(), mappedStatementId, true);
-        if (null != sqlSegment) {
-            plainSelect.setWhere(sqlSegment);
-        }
-    }
-
-}
-
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/annotation/DataColumn.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/annotation/DataColumn.java
new file mode 100644
index 0000000..aca470f
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/annotation/DataColumn.java
@@ -0,0 +1,28 @@
+package org.dromara.common.mybatis.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 鏁版嵁鏉冮檺
+ *
+ * 涓�涓敞瑙e彧鑳藉搴斾竴涓ā鏉�
+ *
+ * @author Lion Li
+ * @version 3.5.0
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface DataColumn {
+
+    /**
+     * 鍗犱綅绗﹀叧閿瓧
+     */
+    String[] key() default "deptName";
+
+    /**
+     * 鍗犱綅绗︽浛鎹㈠��
+     */
+    String[] value() default "dept_id";
+
+}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/annotation/DataPermission.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/annotation/DataPermission.java
new file mode 100644
index 0000000..f4351e3
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/annotation/DataPermission.java
@@ -0,0 +1,18 @@
+package org.dromara.common.mybatis.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 鏁版嵁鏉冮檺缁�
+ *
+ * @author Lion Li
+ * @version 3.5.0
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface DataPermission {
+
+    DataColumn[] value();
+
+}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/config/MybatisPlusConfig.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/config/MybatisPlusConfig.java
new file mode 100644
index 0000000..1fe7834
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/config/MybatisPlusConfig.java
@@ -0,0 +1,102 @@
+package org.dromara.common.mybatis.config;
+
+import cn.hutool.core.net.NetUtil;
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator;
+import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.dromara.common.mybatis.handler.InjectionMetaObjectHandler;
+import org.dromara.common.mybatis.interceptor.PlusDataPermissionInterceptor;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+/**
+ * mybatis-plus閰嶇疆绫�(涓嬫柟娉ㄩ噴鏈夋彃浠朵粙缁�)
+ *
+ * @author Lion Li
+ */
+@EnableTransactionManagement(proxyTargetClass = true)
+@AutoConfiguration
+@MapperScan("${mybatis-plus.mapperPackage}")
+public class MybatisPlusConfig {
+
+    @Bean
+    public MybatisPlusInterceptor mybatisPlusInterceptor() {
+        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+        // 鏁版嵁鏉冮檺澶勭悊
+        interceptor.addInnerInterceptor(dataPermissionInterceptor());
+        // 鍒嗛〉鎻掍欢
+        interceptor.addInnerInterceptor(paginationInnerInterceptor());
+        // 涔愯閿佹彃浠�
+        interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor());
+        return interceptor;
+    }
+
+    /**
+     * 鏁版嵁鏉冮檺鎷︽埅鍣�
+     */
+    public PlusDataPermissionInterceptor dataPermissionInterceptor() {
+        return new PlusDataPermissionInterceptor();
+    }
+
+    /**
+     * 鍒嗛〉鎻掍欢锛岃嚜鍔ㄨ瘑鍒暟鎹簱绫诲瀷
+     */
+    public PaginationInnerInterceptor paginationInnerInterceptor() {
+        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
+        // 璁剧疆鏈�澶у崟椤甸檺鍒舵暟閲忥紝榛樿 500 鏉★紝-1 涓嶅彈闄愬埗
+        paginationInnerInterceptor.setMaxLimit(-1L);
+        // 鍒嗛〉鍚堢悊鍖�
+        paginationInnerInterceptor.setOverflow(true);
+        return paginationInnerInterceptor;
+    }
+
+    /**
+     * 涔愯閿佹彃浠�
+     */
+    public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor() {
+        return new OptimisticLockerInnerInterceptor();
+    }
+
+    /**
+     * 鍏冨璞″瓧娈靛~鍏呮帶鍒跺櫒
+     */
+    @Bean
+    public MetaObjectHandler metaObjectHandler() {
+        return new InjectionMetaObjectHandler();
+    }
+
+    /**
+     * 浣跨敤缃戝崱淇℃伅缁戝畾闆姳鐢熸垚鍣�
+     * 闃叉闆嗙兢闆姳ID閲嶅
+     */
+    @Bean
+    public IdentifierGenerator idGenerator() {
+        return new DefaultIdentifierGenerator(NetUtil.getLocalhost());
+    }
+
+    /**
+     * PaginationInnerInterceptor 鍒嗛〉鎻掍欢锛岃嚜鍔ㄨ瘑鍒暟鎹簱绫诲瀷
+     * https://baomidou.com/pages/97710a/
+     * OptimisticLockerInnerInterceptor 涔愯閿佹彃浠�
+     * https://baomidou.com/pages/0d93c0/
+     * MetaObjectHandler 鍏冨璞″瓧娈靛~鍏呮帶鍒跺櫒
+     * https://baomidou.com/pages/4c6bcf/
+     * ISqlInjector sql娉ㄥ叆鍣�
+     * https://baomidou.com/pages/42ea4a/
+     * BlockAttackInnerInterceptor 濡傛灉鏄鍏ㄨ〃鐨勫垹闄ゆ垨鏇存柊鎿嶄綔锛屽氨浼氱粓姝㈣鎿嶄綔
+     * https://baomidou.com/pages/f9a237/
+     * IllegalSQLInnerInterceptor sql鎬ц兘瑙勮寖鎻掍欢(鍨冨溇SQL鎷︽埅)
+     * IdentifierGenerator 鑷畾涔変富閿瓥鐣�
+     * https://baomidou.com/pages/568eb2/
+     * TenantLineInnerInterceptor 澶氱鎴锋彃浠�
+     * https://baomidou.com/pages/aef2f2/
+     * DynamicTableNameInnerInterceptor 鍔ㄦ�佽〃鍚嶆彃浠�
+     * https://baomidou.com/pages/2a45ff/
+     */
+
+}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/domain/BaseEntity.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/domain/BaseEntity.java
new file mode 100644
index 0000000..820b49a
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/domain/BaseEntity.java
@@ -0,0 +1,71 @@
+package org.dromara.common.mybatis.core.domain;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Entity鍩虹被
+ *
+ * @author Lion Li
+ */
+
+@Data
+public class BaseEntity implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鎼滅储鍊�
+     */
+    @JsonIgnore
+    @TableField(exist = false)
+    private String searchValue;
+
+    /**
+     * 鍒涘缓閮ㄩ棬
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Long createDept;
+
+    /**
+     * 鍒涘缓鑰�
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Long createBy;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Date createTime;
+
+    /**
+     * 鏇存柊鑰�
+     */
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Long updateBy;
+
+    /**
+     * 鏇存柊鏃堕棿
+     */
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Date updateTime;
+
+    /**
+     * 璇锋眰鍙傛暟
+     */
+    @JsonInclude(JsonInclude.Include.NON_EMPTY)
+    @TableField(exist = false)
+    private Map<String, Object> params = new HashMap<>();
+
+}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/mapper/BaseMapperPlus.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/mapper/BaseMapperPlus.java
new file mode 100644
index 0000000..1f36f04
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/mapper/BaseMapperPlus.java
@@ -0,0 +1,198 @@
+package org.dromara.common.mybatis.core.mapper;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.toolkit.Db;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.apache.ibatis.logging.Log;
+import org.apache.ibatis.logging.LogFactory;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * 鑷畾涔� Mapper 鎺ュ彛, 瀹炵幇 鑷畾涔夋墿灞�
+ *
+ * @param <T> table 娉涘瀷
+ * @param <V> vo 娉涘瀷
+ * @author Lion Li
+ * @since 2021-05-13
+ */
+@SuppressWarnings("unchecked")
+public interface BaseMapperPlus<T, V> extends BaseMapper<T> {
+
+    Log log = LogFactory.getLog(BaseMapperPlus.class);
+
+    default Class<V> currentVoClass() {
+        return (Class<V>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseMapperPlus.class, 1);
+    }
+
+    default Class<T> currentModelClass() {
+        return (Class<T>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseMapperPlus.class, 0);
+    }
+
+    default List<T> selectList() {
+        return this.selectList(new QueryWrapper<>());
+    }
+
+    /**
+     * 鎵归噺鎻掑叆
+     */
+    default boolean insertBatch(Collection<T> entityList) {
+        return Db.saveBatch(entityList);
+    }
+
+    /**
+     * 鎵归噺鏇存柊
+     */
+    default boolean updateBatchById(Collection<T> entityList) {
+        return Db.updateBatchById(entityList);
+    }
+
+    /**
+     * 鎵归噺鎻掑叆鎴栨洿鏂�
+     */
+    default boolean insertOrUpdateBatch(Collection<T> entityList) {
+        return Db.saveOrUpdateBatch(entityList);
+    }
+
+    /**
+     * 鎵归噺鎻掑叆(鍖呭惈闄愬埗鏉℃暟)
+     */
+    default boolean insertBatch(Collection<T> entityList, int batchSize) {
+        return Db.saveBatch(entityList, batchSize);
+    }
+
+    /**
+     * 鎵归噺鏇存柊(鍖呭惈闄愬埗鏉℃暟)
+     */
+    default boolean updateBatchById(Collection<T> entityList, int batchSize) {
+        return Db.updateBatchById(entityList, batchSize);
+    }
+
+    /**
+     * 鎵归噺鎻掑叆鎴栨洿鏂�(鍖呭惈闄愬埗鏉℃暟)
+     */
+    default boolean insertOrUpdateBatch(Collection<T> entityList, int batchSize) {
+        return Db.saveOrUpdateBatch(entityList, batchSize);
+    }
+
+    /**
+     * 鎻掑叆鎴栨洿鏂�(鍖呭惈闄愬埗鏉℃暟)
+     */
+    default boolean insertOrUpdate(T entity) {
+        return Db.saveOrUpdate(entity);
+    }
+
+    default V selectVoById(Serializable id) {
+        return selectVoById(id, this.currentVoClass());
+    }
+
+    /**
+     * 鏍规嵁 ID 鏌ヨ
+     */
+    default <C> C selectVoById(Serializable id, Class<C> voClass) {
+        T obj = this.selectById(id);
+        if (ObjectUtil.isNull(obj)) {
+            return null;
+        }
+        return MapstructUtils.convert(obj, voClass);
+    }
+
+    default List<V> selectVoBatchIds(Collection<? extends Serializable> idList) {
+        return selectVoBatchIds(idList, this.currentVoClass());
+    }
+
+    /**
+     * 鏌ヨ锛堟牴鎹甀D 鎵归噺鏌ヨ锛�
+     */
+    default <C> List<C> selectVoBatchIds(Collection<? extends Serializable> idList, Class<C> voClass) {
+        List<T> list = this.selectBatchIds(idList);
+        if (CollUtil.isEmpty(list)) {
+            return CollUtil.newArrayList();
+        }
+        return MapstructUtils.convert(list, voClass);
+    }
+
+    default List<V> selectVoByMap(Map<String, Object> map) {
+        return selectVoByMap(map, this.currentVoClass());
+    }
+
+    /**
+     * 鏌ヨ锛堟牴鎹� columnMap 鏉′欢锛�
+     */
+    default <C> List<C> selectVoByMap(Map<String, Object> map, Class<C> voClass) {
+        List<T> list = this.selectByMap(map);
+        if (CollUtil.isEmpty(list)) {
+            return CollUtil.newArrayList();
+        }
+        return MapstructUtils.convert(list, voClass);
+    }
+
+    default V selectVoOne(Wrapper<T> wrapper) {
+        return selectVoOne(wrapper, this.currentVoClass());
+    }
+
+    /**
+     * 鏍规嵁 entity 鏉′欢锛屾煡璇竴鏉¤褰�
+     */
+    default <C> C selectVoOne(Wrapper<T> wrapper, Class<C> voClass) {
+        T obj = this.selectOne(wrapper);
+        if (ObjectUtil.isNull(obj)) {
+            return null;
+        }
+        return MapstructUtils.convert(obj, voClass);
+    }
+
+    default List<V> selectVoList() {
+        return selectVoList(new QueryWrapper<>(), this.currentVoClass());
+    }
+
+    default List<V> selectVoList(Wrapper<T> wrapper) {
+        return selectVoList(wrapper, this.currentVoClass());
+    }
+
+    /**
+     * 鏍规嵁 entity 鏉′欢锛屾煡璇㈠叏閮ㄨ褰�
+     */
+    default <C> List<C> selectVoList(Wrapper<T> wrapper, Class<C> voClass) {
+        List<T> list = this.selectList(wrapper);
+        if (CollUtil.isEmpty(list)) {
+            return CollUtil.newArrayList();
+        }
+        return MapstructUtils.convert(list, voClass);
+    }
+
+    default <P extends IPage<V>> P selectVoPage(IPage<T> page, Wrapper<T> wrapper) {
+        return selectVoPage(page, wrapper, this.currentVoClass());
+    }
+
+    /**
+     * 鍒嗛〉鏌ヨVO
+     */
+    default <C, P extends IPage<C>> P selectVoPage(IPage<T> page, Wrapper<T> wrapper, Class<C> voClass) {
+        IPage<T> pageData = this.selectPage(page, wrapper);
+        IPage<C> voPage = new Page<>(pageData.getCurrent(), pageData.getSize(), pageData.getTotal());
+        if (CollUtil.isEmpty(pageData.getRecords())) {
+            return (P) voPage;
+        }
+        voPage.setRecords(MapstructUtils.convert(pageData.getRecords(), voClass));
+        return (P) voPage;
+    }
+
+    default <C> List<C> selectObjs(Wrapper<T> wrapper, Function<? super Object, C> mapper) {
+        return this.selectObjs(wrapper).stream().filter(Objects::nonNull).map(mapper).collect(Collectors.toList());
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/page/PageQuery.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/page/PageQuery.java
new file mode 100644
index 0000000..8ef4a57
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/page/PageQuery.java
@@ -0,0 +1,114 @@
+package org.dromara.common.mybatis.core.page;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.metadata.OrderItem;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.core.utils.sql.SqlUtil;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 鍒嗛〉鏌ヨ瀹炰綋绫�
+ *
+ * @author Lion Li
+ */
+
+@Data
+public class PageQuery implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鍒嗛〉澶у皬
+     */
+    private Integer pageSize;
+
+    /**
+     * 褰撳墠椤垫暟
+     */
+    private Integer pageNum;
+
+    /**
+     * 鎺掑簭鍒�
+     */
+    private String orderByColumn;
+
+    /**
+     * 鎺掑簭鐨勬柟鍚慸esc鎴栬�卆sc
+     */
+    private String isAsc;
+
+    /**
+     * 褰撳墠璁板綍璧峰绱㈠紩 榛樿鍊�
+     */
+    public static final int DEFAULT_PAGE_NUM = 1;
+
+    /**
+     * 姣忛〉鏄剧ず璁板綍鏁� 榛樿鍊� 榛樿鏌ュ叏閮�
+     */
+    public static final int DEFAULT_PAGE_SIZE = Integer.MAX_VALUE;
+
+    public <T> Page<T> build() {
+        Integer pageNum = ObjectUtil.defaultIfNull(getPageNum(), DEFAULT_PAGE_NUM);
+        Integer pageSize = ObjectUtil.defaultIfNull(getPageSize(), DEFAULT_PAGE_SIZE);
+        if (pageNum <= 0) {
+            pageNum = DEFAULT_PAGE_NUM;
+        }
+        Page<T> page = new Page<>(pageNum, pageSize);
+        List<OrderItem> orderItems = buildOrderItem();
+        if (CollUtil.isNotEmpty(orderItems)) {
+            page.addOrder(orderItems);
+        }
+        return page;
+    }
+
+    /**
+     * 鏋勫缓鎺掑簭
+     *
+     * 鏀寔鐨勭敤娉曞涓�:
+     * {isAsc:"asc",orderByColumn:"id"} order by id asc
+     * {isAsc:"asc",orderByColumn:"id,createTime"} order by id asc,create_time asc
+     * {isAsc:"desc",orderByColumn:"id,createTime"} order by id desc,create_time desc
+     * {isAsc:"asc,desc",orderByColumn:"id,createTime"} order by id asc,create_time desc
+     */
+    private List<OrderItem> buildOrderItem() {
+        if (StringUtils.isBlank(orderByColumn) || StringUtils.isBlank(isAsc)) {
+            return null;
+        }
+        String orderBy = SqlUtil.escapeOrderBySql(orderByColumn);
+        orderBy = StringUtils.toUnderScoreCase(orderBy);
+
+        // 鍏煎鍓嶇鎺掑簭绫诲瀷
+        isAsc = StringUtils.replaceEach(isAsc, new String[]{"ascending", "descending"}, new String[]{"asc", "desc"});
+
+        String[] orderByArr = orderBy.split(StringUtils.SEPARATOR);
+        String[] isAscArr = isAsc.split(StringUtils.SEPARATOR);
+        if (isAscArr.length != 1 && isAscArr.length != orderByArr.length) {
+            throw new ServiceException("鎺掑簭鍙傛暟鏈夎");
+        }
+
+        List<OrderItem> list = new ArrayList<>();
+        // 姣忎釜瀛楁鍚勮嚜鎺掑簭
+        for (int i = 0; i < orderByArr.length; i++) {
+            String orderByStr = orderByArr[i];
+            String isAscStr = isAscArr.length == 1 ? isAscArr[0] : isAscArr[i];
+            if ("asc".equals(isAscStr)) {
+                list.add(OrderItem.asc(orderByStr));
+            } else if ("desc".equals(isAscStr)) {
+                list.add(OrderItem.desc(orderByStr));
+            } else {
+                throw new ServiceException("鎺掑簭鍙傛暟鏈夎");
+            }
+        }
+        return list;
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/page/TableDataInfo.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/page/TableDataInfo.java
new file mode 100644
index 0000000..a4b6799
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/page/TableDataInfo.java
@@ -0,0 +1,81 @@
+package org.dromara.common.mybatis.core.page;
+
+import cn.hutool.http.HttpStatus;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 琛ㄦ牸鍒嗛〉鏁版嵁瀵硅薄
+ *
+ * @author Lion Li
+ */
+
+@Data
+@NoArgsConstructor
+public class TableDataInfo<T> implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鎬昏褰曟暟
+     */
+    private long total;
+
+    /**
+     * 鍒楄〃鏁版嵁
+     */
+    private List<T> rows;
+
+    /**
+     * 娑堟伅鐘舵�佺爜
+     */
+    private int code;
+
+    /**
+     * 娑堟伅鍐呭
+     */
+    private String msg;
+
+    /**
+     * 鍒嗛〉
+     *
+     * @param list  鍒楄〃鏁版嵁
+     * @param total 鎬昏褰曟暟
+     */
+    public TableDataInfo(List<T> list, long total) {
+        this.rows = list;
+        this.total = total;
+    }
+
+    public static <T> TableDataInfo<T> build(IPage<T> page) {
+        TableDataInfo<T> rspData = new TableDataInfo<>();
+        rspData.setCode(HttpStatus.HTTP_OK);
+        rspData.setMsg("鏌ヨ鎴愬姛");
+        rspData.setRows(page.getRecords());
+        rspData.setTotal(page.getTotal());
+        return rspData;
+    }
+
+    public static <T> TableDataInfo<T> build(List<T> list) {
+        TableDataInfo<T> rspData = new TableDataInfo<>();
+        rspData.setCode(HttpStatus.HTTP_OK);
+        rspData.setMsg("鏌ヨ鎴愬姛");
+        rspData.setRows(list);
+        rspData.setTotal(list.size());
+        return rspData;
+    }
+
+    public static <T> TableDataInfo<T> build() {
+        TableDataInfo<T> rspData = new TableDataInfo<>();
+        rspData.setCode(HttpStatus.HTTP_OK);
+        rspData.setMsg("鏌ヨ鎴愬姛");
+        return rspData;
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/enums/DataBaseType.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/enums/DataBaseType.java
new file mode 100644
index 0000000..93487e9
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/enums/DataBaseType.java
@@ -0,0 +1,49 @@
+package org.dromara.common.mybatis.enums;
+
+import org.dromara.common.core.utils.StringUtils;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 鏁版嵁搴撶被鍨�
+ *
+ * @author Lion Li
+ */
+@Getter
+@AllArgsConstructor
+public enum DataBaseType {
+
+    /**
+     * MySQL
+     */
+    MY_SQL("MySQL"),
+
+    /**
+     * Oracle
+     */
+    ORACLE("Oracle"),
+
+    /**
+     * PostgreSQL
+     */
+    POSTGRE_SQL("PostgreSQL"),
+
+    /**
+     * SQL Server
+     */
+    SQL_SERVER("Microsoft SQL Server");
+
+    private final String type;
+
+    public static DataBaseType find(String databaseProductName) {
+        if (StringUtils.isBlank(databaseProductName)) {
+            return null;
+        }
+        for (DataBaseType type : values()) {
+            if (type.getType().equals(databaseProductName)) {
+                return type;
+            }
+        }
+        return null;
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/enums/DataScopeType.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/enums/DataScopeType.java
new file mode 100644
index 0000000..18d536e
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/enums/DataScopeType.java
@@ -0,0 +1,73 @@
+package org.dromara.common.mybatis.enums;
+
+import org.dromara.common.core.utils.StringUtils;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.dromara.common.mybatis.helper.DataPermissionHelper;
+
+/**
+ * 鏁版嵁鏉冮檺绫诲瀷
+ * <p>
+ * 璇硶鏀寔 spel 妯℃澘琛ㄨ揪寮�
+ * <p>
+ * 鍐呯疆鏁版嵁 user 褰撳墠鐢ㄦ埛 鍐呭鍙傝�� LoginUser
+ * 濡傞渶鎵╁睍鏁版嵁 鍙娇鐢� {@link DataPermissionHelper} 鎿嶄綔
+ * 鍐呯疆鏈嶅姟 sdss 绯荤粺鏁版嵁鏉冮檺鏈嶅姟 鍐呭鍙傝�� SysDataScopeService
+ * 濡傞渶鎵╁睍鏇村鑷畾涔夋湇鍔� 鍙互鍙傝�� sdss 鑷缂栧啓
+ *
+ * @author Lion Li
+ * @version 3.5.0
+ */
+@Getter
+@AllArgsConstructor
+public enum DataScopeType {
+
+    /**
+     * 鍏ㄩ儴鏁版嵁鏉冮檺
+     */
+    ALL("1", "", ""),
+
+    /**
+     * 鑷畾鏁版嵁鏉冮檺
+     */
+    CUSTOM("2", " #{#deptName} IN ( #{@sdss.getRoleCustom( #user.roleId )} ) ", ""),
+
+    /**
+     * 閮ㄩ棬鏁版嵁鏉冮檺
+     */
+    DEPT("3", " #{#deptName} = #{#user.deptId} ", ""),
+
+    /**
+     * 閮ㄩ棬鍙婁互涓嬫暟鎹潈闄�
+     */
+    DEPT_AND_CHILD("4", " #{#deptName} IN ( #{@sdss.getDeptAndChild( #user.deptId )} )", ""),
+
+    /**
+     * 浠呮湰浜烘暟鎹潈闄�
+     */
+    SELF("5", " #{#userName} = #{#user.userId} ", " 1 = 0 ");
+
+    private final String code;
+
+    /**
+     * 璇硶 閲囩敤 spel 妯℃澘琛ㄨ揪寮�
+     */
+    private final String sqlTemplate;
+
+    /**
+     * 涓嶆弧瓒� sqlTemplate 鍒欏~鍏�
+     */
+    private final String elseSql;
+
+    public static DataScopeType findCode(String code) {
+        if (StringUtils.isBlank(code)) {
+            return null;
+        }
+        for (DataScopeType type : values()) {
+            if (type.getCode().equals(code)) {
+                return type;
+            }
+        }
+        return null;
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/InjectionMetaObjectHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/InjectionMetaObjectHandler.java
new file mode 100644
index 0000000..63653de
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/InjectionMetaObjectHandler.java
@@ -0,0 +1,81 @@
+package org.dromara.common.mybatis.handler;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.http.HttpStatus;
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import org.dromara.common.core.domain.model.LoginUser;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.satoken.utils.LoginHelper;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.reflection.MetaObject;
+
+import java.util.Date;
+
+/**
+ * MP娉ㄥ叆澶勭悊鍣�
+ *
+ * @author Lion Li
+ * @date 2021/4/25
+ */
+@Slf4j
+public class InjectionMetaObjectHandler implements MetaObjectHandler {
+
+    @Override
+    public void insertFill(MetaObject metaObject) {
+        try {
+            if (ObjectUtil.isNotNull(metaObject) && metaObject.getOriginalObject() instanceof BaseEntity baseEntity) {
+                Date current = ObjectUtil.isNotNull(baseEntity.getCreateTime())
+                    ? baseEntity.getCreateTime() : new Date();
+                baseEntity.setCreateTime(current);
+                baseEntity.setUpdateTime(current);
+                LoginUser loginUser = getLoginUser();
+                if (ObjectUtil.isNotNull(loginUser)) {
+                    Long userId = ObjectUtil.isNotNull(baseEntity.getCreateBy())
+                        ? baseEntity.getCreateBy() : loginUser.getUserId();
+                    // 褰撳墠宸茬櫥褰� 涓� 鍒涘缓浜轰负绌� 鍒欏~鍏�
+                    baseEntity.setCreateBy(userId);
+                    // 褰撳墠宸茬櫥褰� 涓� 鏇存柊浜轰负绌� 鍒欏~鍏�
+                    baseEntity.setUpdateBy(userId);
+                    baseEntity.setCreateDept(ObjectUtil.isNotNull(baseEntity.getCreateDept())
+                        ? baseEntity.getCreateDept() : loginUser.getDeptId());
+                }
+            }
+        } catch (Exception e) {
+            throw new ServiceException("鑷姩娉ㄥ叆寮傚父 => " + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED);
+        }
+    }
+
+    @Override
+    public void updateFill(MetaObject metaObject) {
+        try {
+            if (ObjectUtil.isNotNull(metaObject) && metaObject.getOriginalObject() instanceof BaseEntity baseEntity) {
+                Date current = new Date();
+                // 鏇存柊鏃堕棿濉厖(涓嶇涓轰笉涓虹┖)
+                baseEntity.setUpdateTime(current);
+                LoginUser loginUser = getLoginUser();
+                // 褰撳墠宸茬櫥褰� 鏇存柊浜哄~鍏�(涓嶇涓轰笉涓虹┖)
+                if (ObjectUtil.isNotNull(loginUser)) {
+                    baseEntity.setUpdateBy(loginUser.getUserId());
+                }
+            }
+        } catch (Exception e) {
+            throw new ServiceException("鑷姩娉ㄥ叆寮傚父 => " + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED);
+        }
+    }
+
+    /**
+     * 鑾峰彇鐧诲綍鐢ㄦ埛鍚�
+     */
+    private LoginUser getLoginUser() {
+        LoginUser loginUser;
+        try {
+            loginUser = LoginHelper.getLoginUser();
+        } catch (Exception e) {
+            log.warn("鑷姩娉ㄥ叆璀﹀憡 => 鐢ㄦ埛鏈櫥褰�");
+            return null;
+        }
+        return loginUser;
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java
new file mode 100644
index 0000000..64463e6
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java
@@ -0,0 +1,46 @@
+package org.dromara.common.mybatis.handler;
+
+import org.dromara.common.core.domain.R;
+import lombok.extern.slf4j.Slf4j;
+import org.mybatis.spring.MyBatisSystemException;
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import jakarta.servlet.http.HttpServletRequest;
+
+/**
+ * Mybatis寮傚父澶勭悊鍣�
+ *
+ * @author Lion Li
+ */
+@Slf4j
+@RestControllerAdvice
+public class MybatisExceptionHandler {
+
+    /**
+     * 涓婚敭鎴朥NIQUE绱㈠紩锛屾暟鎹噸澶嶅紓甯�
+     */
+    @ExceptionHandler(DuplicateKeyException.class)
+    public R<Void> handleDuplicateKeyException(DuplicateKeyException e, HttpServletRequest request) {
+        String requestURI = request.getRequestURI();
+        log.error("璇锋眰鍦板潃'{}',鏁版嵁搴撲腑宸插瓨鍦ㄨ褰�'{}'", requestURI, e.getMessage());
+        return R.fail("鏁版嵁搴撲腑宸插瓨鍦ㄨ璁板綍锛岃鑱旂郴绠$悊鍛樼‘璁�");
+    }
+
+    /**
+     * Mybatis绯荤粺寮傚父 閫氱敤澶勭悊
+     */
+    @ExceptionHandler(MyBatisSystemException.class)
+    public R<Void> handleCannotFindDataSourceException(MyBatisSystemException e, HttpServletRequest request) {
+        String requestURI = request.getRequestURI();
+        String message = e.getMessage();
+        if (message.contains("CannotFindDataSourceException")) {
+            log.error("璇锋眰鍦板潃'{}', 鏈壘鍒版暟鎹簮", requestURI);
+            return R.fail("鏈壘鍒版暟鎹簮锛岃鑱旂郴绠$悊鍛樼‘璁�");
+        }
+        log.error("璇锋眰鍦板潃'{}', Mybatis绯荤粺寮傚父", requestURI, e);
+        return R.fail(message);
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java
new file mode 100644
index 0000000..c9a578f
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java
@@ -0,0 +1,198 @@
+package org.dromara.common.mybatis.handler;
+
+import cn.hutool.core.annotation.AnnotationUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.collection.ConcurrentHashSet;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.ClassUtil;
+import cn.hutool.core.util.ObjectUtil;
+import org.dromara.common.core.domain.dto.RoleDTO;
+import org.dromara.common.core.domain.model.LoginUser;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.StreamUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.annotation.DataColumn;
+import org.dromara.common.mybatis.annotation.DataPermission;
+import org.dromara.common.mybatis.enums.DataScopeType;
+import org.dromara.common.mybatis.helper.DataPermissionHelper;
+import org.dromara.common.satoken.utils.LoginHelper;
+import lombok.extern.slf4j.Slf4j;
+import net.sf.jsqlparser.JSQLParserException;
+import net.sf.jsqlparser.expression.Expression;
+import net.sf.jsqlparser.expression.Parenthesis;
+import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
+import net.sf.jsqlparser.parser.CCJSqlParserUtil;
+import org.springframework.context.expression.BeanFactoryResolver;
+import org.springframework.expression.BeanResolver;
+import org.springframework.expression.ExpressionParser;
+import org.springframework.expression.ParserContext;
+import org.springframework.expression.common.TemplateParserContext;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.expression.spel.support.StandardEvaluationContext;
+
+import java.lang.reflect.Method;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
+
+/**
+ * 鏁版嵁鏉冮檺杩囨护
+ *
+ * @author Lion Li
+ * @version 3.5.0
+ */
+@Slf4j
+public class PlusDataPermissionHandler {
+
+    /**
+     * 鏂规硶鎴栫被(鍚嶇О) 涓� 娉ㄨВ鐨勬槧灏勫叧绯荤紦瀛�
+     */
+    private final Map<String, DataPermission> dataPermissionCacheMap = new ConcurrentHashMap<>();
+
+    /**
+     * 鏃犳晥娉ㄨВ鏂规硶缂撳瓨鐢ㄤ簬蹇�熻繑鍥�
+     */
+    private final Set<String> invalidCacheSet = new ConcurrentHashSet<>();
+
+    /**
+     * spel 瑙f瀽鍣�
+     */
+    private final ExpressionParser parser = new SpelExpressionParser();
+    private final ParserContext parserContext = new TemplateParserContext();
+    /**
+     * bean瑙f瀽鍣� 鐢ㄤ簬澶勭悊 spel 琛ㄨ揪寮忎腑瀵� bean 鐨勮皟鐢�
+     */
+    private final BeanResolver beanResolver = new BeanFactoryResolver(SpringUtils.getBeanFactory());
+
+
+    public Expression getSqlSegment(Expression where, String mappedStatementId, boolean isSelect) {
+        DataColumn[] dataColumns = findAnnotation(mappedStatementId);
+        if (ArrayUtil.isEmpty(dataColumns)) {
+            invalidCacheSet.add(mappedStatementId);
+            return where;
+        }
+        LoginUser currentUser = DataPermissionHelper.getVariable("user");
+        if (ObjectUtil.isNull(currentUser)) {
+            currentUser = LoginHelper.getLoginUser();
+            DataPermissionHelper.setVariable("user", currentUser);
+        }
+        // 濡傛灉鏄秴绾х鐞嗗憳鎴栫鎴风鐞嗗憳锛屽垯涓嶈繃婊ゆ暟鎹�
+        if (LoginHelper.isSuperAdmin() || LoginHelper.isTenantAdmin()) {
+            return where;
+        }
+        String dataFilterSql = buildDataFilter(dataColumns, isSelect);
+        if (StringUtils.isBlank(dataFilterSql)) {
+            return where;
+        }
+        try {
+            Expression expression = CCJSqlParserUtil.parseExpression(dataFilterSql);
+            // 鏁版嵁鏉冮檺浣跨敤鍗曠嫭鐨勬嫭鍙� 闃叉涓庡叾浠栨潯浠跺啿绐�
+            Parenthesis parenthesis = new Parenthesis(expression);
+            if (ObjectUtil.isNotNull(where)) {
+                return new AndExpression(where, parenthesis);
+            } else {
+                return parenthesis;
+            }
+        } catch (JSQLParserException e) {
+            throw new ServiceException("鏁版嵁鏉冮檺瑙f瀽寮傚父 => " + e.getMessage());
+        }
+    }
+
+    /**
+     * 鏋勯�犳暟鎹繃婊ql
+     */
+    private String buildDataFilter(DataColumn[] dataColumns, boolean isSelect) {
+        // 鏇存柊鎴栧垹闄ら渶婊¤冻鎵�鏈夋潯浠�
+        String joinStr = isSelect ? " OR " : " AND ";
+        LoginUser user = DataPermissionHelper.getVariable("user");
+        StandardEvaluationContext context = new StandardEvaluationContext();
+        context.setBeanResolver(beanResolver);
+        DataPermissionHelper.getContext().forEach(context::setVariable);
+        Set<String> conditions = new HashSet<>();
+        for (RoleDTO role : user.getRoles()) {
+            user.setRoleId(role.getRoleId());
+            // 鑾峰彇瑙掕壊鏉冮檺娉涘瀷
+            DataScopeType type = DataScopeType.findCode(role.getDataScope());
+            if (ObjectUtil.isNull(type)) {
+                throw new ServiceException("瑙掕壊鏁版嵁鑼冨洿寮傚父 => " + role.getDataScope());
+            }
+            // 鍏ㄩ儴鏁版嵁鏉冮檺鐩存帴杩斿洖
+            if (type == DataScopeType.ALL) {
+                return "";
+            }
+            boolean isSuccess = false;
+            for (DataColumn dataColumn : dataColumns) {
+                if (dataColumn.key().length != dataColumn.value().length) {
+                    throw new ServiceException("瑙掕壊鏁版嵁鑼冨洿寮傚父 => key涓巚alue闀垮害涓嶅尮閰�");
+                }
+                // 涓嶅寘鍚� key 鍙橀噺 鍒欎笉澶勭悊
+                if (!StringUtils.containsAny(type.getSqlTemplate(),
+                    Arrays.stream(dataColumn.key()).map(key -> "#" + key).toArray(String[]::new)
+                )) {
+                    continue;
+                }
+                // 璁剧疆娉ㄨВ鍙橀噺 key 涓鸿〃杈惧紡鍙橀噺 value 涓哄彉閲忓��
+                for (int i = 0; i < dataColumn.key().length; i++) {
+                    context.setVariable(dataColumn.key()[i], dataColumn.value()[i]);
+                }
+
+                // 瑙f瀽sql妯℃澘骞跺~鍏�
+                String sql = parser.parseExpression(type.getSqlTemplate(), parserContext).getValue(context, String.class);
+                conditions.add(joinStr + sql);
+                isSuccess = true;
+            }
+            // 鏈鐞嗘垚鍔熷垯濉厖鍏滃簳鏂规
+            if (!isSuccess && StringUtils.isNotBlank(type.getElseSql())) {
+                conditions.add(joinStr + type.getElseSql());
+            }
+        }
+
+        if (CollUtil.isNotEmpty(conditions)) {
+            String sql = StreamUtils.join(conditions, Function.identity(), "");
+            return sql.substring(joinStr.length());
+        }
+        return "";
+    }
+
+    private DataColumn[] findAnnotation(String mappedStatementId) {
+        StringBuilder sb = new StringBuilder(mappedStatementId);
+        int index = sb.lastIndexOf(".");
+        String clazzName = sb.substring(0, index);
+        String methodName = sb.substring(index + 1, sb.length());
+        Class<?> clazz = ClassUtil.loadClass(clazzName);
+        List<Method> methods = Arrays.stream(ClassUtil.getDeclaredMethods(clazz))
+            .filter(method -> method.getName().equals(methodName)).toList();
+        DataPermission dataPermission;
+        // 鑾峰彇鏂规硶娉ㄨВ
+        for (Method method : methods) {
+            dataPermission = dataPermissionCacheMap.get(mappedStatementId);
+            if (ObjectUtil.isNotNull(dataPermission)) {
+                return dataPermission.value();
+            }
+            if (AnnotationUtil.hasAnnotation(method, DataPermission.class)) {
+                dataPermission = AnnotationUtil.getAnnotation(method, DataPermission.class);
+                dataPermissionCacheMap.put(mappedStatementId, dataPermission);
+                return dataPermission.value();
+            }
+        }
+        dataPermission = dataPermissionCacheMap.get(clazz.getName());
+        if (ObjectUtil.isNotNull(dataPermission)) {
+            return dataPermission.value();
+        }
+        // 鑾峰彇绫绘敞瑙�
+        if (AnnotationUtil.hasAnnotation(clazz, DataPermission.class)) {
+            dataPermission = AnnotationUtil.getAnnotation(clazz, DataPermission.class);
+            dataPermissionCacheMap.put(clazz.getName(), dataPermission);
+            return dataPermission.value();
+        }
+        return null;
+    }
+
+    /**
+     * 鏄惁涓烘棤鏁堟柟娉� 鏃犳暟鎹潈闄�
+     */
+    public boolean isInvalid(String mappedStatementId) {
+        return invalidCacheSet.contains(mappedStatementId);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataBaseHelper.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataBaseHelper.java
new file mode 100644
index 0000000..4da9659
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataBaseHelper.java
@@ -0,0 +1,72 @@
+package org.dromara.common.mybatis.helper;
+
+import cn.hutool.core.convert.Convert;
+import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.mybatis.enums.DataBaseType;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+
+/**
+ * 鏁版嵁搴撳姪鎵�
+ *
+ * @author Lion Li
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class DataBaseHelper {
+
+    private static final DynamicRoutingDataSource DS = SpringUtils.getBean(DynamicRoutingDataSource.class);
+
+    /**
+     * 鑾峰彇褰撳墠鏁版嵁搴撶被鍨�
+     */
+    public static DataBaseType getDataBaseType() {
+        DataSource dataSource = DS.determineDataSource();
+        try (Connection conn = dataSource.getConnection()) {
+            DatabaseMetaData metaData = conn.getMetaData();
+            String databaseProductName = metaData.getDatabaseProductName();
+            return DataBaseType.find(databaseProductName);
+        } catch (SQLException e) {
+            throw new ServiceException(e.getMessage());
+        }
+    }
+
+    public static boolean isMySql() {
+        return DataBaseType.MY_SQL == getDataBaseType();
+    }
+
+    public static boolean isOracle() {
+        return DataBaseType.ORACLE == getDataBaseType();
+    }
+
+    public static boolean isPostgerSql() {
+        return DataBaseType.POSTGRE_SQL == getDataBaseType();
+    }
+
+    public static boolean isSqlServer() {
+        return DataBaseType.SQL_SERVER == getDataBaseType();
+    }
+
+    public static String findInSet(Object var1, String var2) {
+        DataBaseType dataBasyType = getDataBaseType();
+        String var = Convert.toStr(var1);
+        if (dataBasyType == DataBaseType.SQL_SERVER) {
+            // charindex(',100,' , ',0,100,101,') <> 0
+            return "charindex(',%s,' , ','+%s+',') <> 0".formatted(var, var2);
+        } else if (dataBasyType == DataBaseType.POSTGRE_SQL) {
+            // (select position(',100,' in ',0,100,101,')) <> 0
+            return "(select position(',%s,' in ','||%s||',')) <> 0".formatted(var, var2);
+        } else if (dataBasyType == DataBaseType.ORACLE) {
+            // instr(',0,100,101,' , ',100,') <> 0
+            return "instr(','||%s||',' , ',%s,') <> 0".formatted(var2, var);
+        }
+        // find_in_set(100 , '0,100,101')
+        return "find_in_set('%s' , %s) <> 0".formatted(var, var2);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java
new file mode 100644
index 0000000..32e1bca
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java
@@ -0,0 +1,64 @@
+package org.dromara.common.mybatis.helper;
+
+import cn.dev33.satoken.context.SaHolder;
+import cn.dev33.satoken.context.model.SaStorage;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy;
+import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 鏁版嵁鏉冮檺鍔╂墜
+ *
+ * @author Lion Li
+ * @version 3.5.0
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+@SuppressWarnings("unchecked cast")
+public class DataPermissionHelper {
+
+    private static final String DATA_PERMISSION_KEY = "data:permission";
+
+    public static <T> T getVariable(String key) {
+        Map<String, Object> context = getContext();
+        return (T) context.get(key);
+    }
+
+
+    public static void setVariable(String key, Object value) {
+        Map<String, Object> context = getContext();
+        context.put(key, value);
+    }
+
+    public static Map<String, Object> getContext() {
+        SaStorage saStorage = SaHolder.getStorage();
+        Object attribute = saStorage.get(DATA_PERMISSION_KEY);
+        if (ObjectUtil.isNull(attribute)) {
+            saStorage.set(DATA_PERMISSION_KEY, new HashMap<>());
+            attribute = saStorage.get(DATA_PERMISSION_KEY);
+        }
+        if (attribute instanceof Map map) {
+            return map;
+        }
+        throw new NullPointerException("data permission context type exception");
+    }
+
+    /**
+     * 寮�鍚拷鐣ユ暟鎹潈闄�(寮�鍚悗闇�鎵嬪姩璋冪敤 {@link #disableIgnore()} 鍏抽棴)
+     */
+    public static void enableIgnore() {
+        InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().dataPermission(true).build());
+    }
+
+    /**
+     * 鍏抽棴蹇界暐鏁版嵁鏉冮檺
+     */
+    public static void disableIgnore() {
+        InterceptorIgnoreHelper.clearIgnoreStrategy();
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlusDataPermissionInterceptor.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlusDataPermissionInterceptor.java
new file mode 100644
index 0000000..e49c95b
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlusDataPermissionInterceptor.java
@@ -0,0 +1,107 @@
+package org.dromara.common.mybatis.interceptor;
+
+import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
+import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
+import com.baomidou.mybatisplus.extension.parser.JsqlParserSupport;
+import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
+import org.dromara.common.mybatis.handler.PlusDataPermissionHandler;
+import net.sf.jsqlparser.expression.Expression;
+import net.sf.jsqlparser.statement.delete.Delete;
+import net.sf.jsqlparser.statement.select.PlainSelect;
+import net.sf.jsqlparser.statement.select.Select;
+import net.sf.jsqlparser.statement.select.SelectBody;
+import net.sf.jsqlparser.statement.select.SetOperationList;
+import net.sf.jsqlparser.statement.update.Update;
+import org.apache.ibatis.executor.Executor;
+import org.apache.ibatis.executor.statement.StatementHandler;
+import org.apache.ibatis.mapping.BoundSql;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.mapping.SqlCommandType;
+import org.apache.ibatis.session.ResultHandler;
+import org.apache.ibatis.session.RowBounds;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.List;
+
+/**
+ * 鏁版嵁鏉冮檺鎷︽埅鍣�
+ *
+ * @author Lion Li
+ * @version 3.5.0
+ */
+public class PlusDataPermissionInterceptor extends JsqlParserSupport implements InnerInterceptor {
+
+    private final PlusDataPermissionHandler dataPermissionHandler = new PlusDataPermissionHandler();
+
+    @Override
+    public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
+        // 妫�鏌ュ拷鐣ユ敞瑙�
+        if (InterceptorIgnoreHelper.willIgnoreDataPermission(ms.getId())) {
+            return;
+        }
+        // 妫�鏌ユ槸鍚︽棤鏁� 鏃犳暟鎹潈闄愭敞瑙�
+        if (dataPermissionHandler.isInvalid(ms.getId())) {
+            return;
+        }
+        // 瑙f瀽 sql 鍒嗛厤瀵瑰簲鏂规硶
+        PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
+        mpBs.sql(parserSingle(mpBs.sql(), ms.getId()));
+    }
+
+    @Override
+    public void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) {
+        PluginUtils.MPStatementHandler mpSh = PluginUtils.mpStatementHandler(sh);
+        MappedStatement ms = mpSh.mappedStatement();
+        SqlCommandType sct = ms.getSqlCommandType();
+        if (sct == SqlCommandType.UPDATE || sct == SqlCommandType.DELETE) {
+            if (InterceptorIgnoreHelper.willIgnoreDataPermission(ms.getId())) {
+                return;
+            }
+            PluginUtils.MPBoundSql mpBs = mpSh.mPBoundSql();
+            mpBs.sql(parserMulti(mpBs.sql(), ms.getId()));
+        }
+    }
+
+    @Override
+    protected void processSelect(Select select, int index, String sql, Object obj) {
+        SelectBody selectBody = select.getSelectBody();
+        if (selectBody instanceof PlainSelect) {
+            this.setWhere((PlainSelect) selectBody, (String) obj);
+        } else if (selectBody instanceof SetOperationList setOperationList) {
+            List<SelectBody> selectBodyList = setOperationList.getSelects();
+            selectBodyList.forEach(s -> this.setWhere((PlainSelect) s, (String) obj));
+        }
+    }
+
+    @Override
+    protected void processUpdate(Update update, int index, String sql, Object obj) {
+        Expression sqlSegment = dataPermissionHandler.getSqlSegment(update.getWhere(), (String) obj, false);
+        if (null != sqlSegment) {
+            update.setWhere(sqlSegment);
+        }
+    }
+
+    @Override
+    protected void processDelete(Delete delete, int index, String sql, Object obj) {
+        Expression sqlSegment = dataPermissionHandler.getSqlSegment(delete.getWhere(), (String) obj, false);
+        if (null != sqlSegment) {
+            delete.setWhere(sqlSegment);
+        }
+    }
+
+    /**
+     * 璁剧疆 where 鏉′欢
+     *
+     * @param plainSelect       鏌ヨ瀵硅薄
+     * @param mappedStatementId 鎵ц鏂规硶id
+     */
+    protected void setWhere(PlainSelect plainSelect, String mappedStatementId) {
+        Expression sqlSegment = dataPermissionHandler.getSqlSegment(plainSelect.getWhere(), mappedStatementId, true);
+        if (null != sqlSegment) {
+            plainSelect.setWhere(sqlSegment);
+        }
+    }
+
+}
+
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-mybatis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index dbcd9a1..cc625da 100644
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +1 @@
-com.ruoyi.common.mybatis.config.MybatisPlusConfig
+org.dromara.common.mybatis.config.MybatisPlusConfig
diff --git a/ruoyi-common/ruoyi-common-oss/pom.xml b/ruoyi-common/ruoyi-common-oss/pom.xml
index a1aa4c4..e985d3b 100644
--- a/ruoyi-common/ruoyi-common-oss/pom.xml
+++ b/ruoyi-common/ruoyi-common-oss/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-common</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -18,12 +18,12 @@
 
     <dependencies>
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-json</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-redis</artifactId>
         </dependency>
 
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/constant/OssConstant.java b/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/constant/OssConstant.java
deleted file mode 100644
index 50a3292..0000000
--- a/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/constant/OssConstant.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.ruoyi.common.oss.constant;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * 瀵硅薄瀛樺偍甯搁噺
- *
- * @author Lion Li
- */
-public interface OssConstant {
-
-    /**
-     * 榛樿閰嶇疆KEY
-     */
-    String DEFAULT_CONFIG_KEY = "sys_oss:default_config";
-
-    /**
-     * 棰勮鍒楄〃璧勬簮寮�鍏矺ey
-     */
-    String PEREVIEW_LIST_RESOURCE_KEY = "sys.oss.previewListResource";
-
-    /**
-     * 绯荤粺鏁版嵁ids
-     */
-    List<Long> SYSTEM_DATA_IDS = Arrays.asList(1L, 2L, 3L, 4L);
-
-    /**
-     * 浜戞湇鍔″晢
-     */
-    String[] CLOUD_SERVICE = new String[] {"aliyun", "qcloud", "qiniu", "obs"};
-
-    /**
-     * https 鐘舵��
-     */
-    String IS_HTTPS = "Y";
-
-}
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/core/OssClient.java b/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/core/OssClient.java
deleted file mode 100644
index 924efc1..0000000
--- a/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/core/OssClient.java
+++ /dev/null
@@ -1,245 +0,0 @@
-package com.ruoyi.common.oss.core;
-
-import cn.hutool.core.io.IoUtil;
-import cn.hutool.core.util.IdUtil;
-import com.amazonaws.ClientConfiguration;
-import com.amazonaws.HttpMethod;
-import com.amazonaws.Protocol;
-import com.amazonaws.auth.AWSCredentials;
-import com.amazonaws.auth.AWSCredentialsProvider;
-import com.amazonaws.auth.AWSStaticCredentialsProvider;
-import com.amazonaws.auth.BasicAWSCredentials;
-import com.amazonaws.client.builder.AwsClientBuilder;
-import com.amazonaws.services.s3.AmazonS3;
-import com.amazonaws.services.s3.AmazonS3Client;
-import com.amazonaws.services.s3.AmazonS3ClientBuilder;
-import com.amazonaws.services.s3.model.*;
-import com.ruoyi.common.core.utils.DateUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.oss.constant.OssConstant;
-import com.ruoyi.common.oss.entity.UploadResult;
-import com.ruoyi.common.oss.enumd.AccessPolicyType;
-import com.ruoyi.common.oss.enumd.PolicyType;
-import com.ruoyi.common.oss.exception.OssException;
-import com.ruoyi.common.oss.properties.OssProperties;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Date;
-
-/**
- * S3 瀛樺偍鍗忚 鎵�鏈夊吋瀹筍3鍗忚鐨勪簯鍘傚晢鍧囨敮鎸�
- * 闃块噷浜� 鑵捐浜� 涓冪墰浜� minio
- *
- * @author Lion Li
- */
-public class OssClient {
-
-    private final String configKey;
-
-    private final OssProperties properties;
-
-    private final AmazonS3 client;
-
-    public OssClient(String configKey, OssProperties ossProperties) {
-        this.configKey = configKey;
-        this.properties = ossProperties;
-        try {
-            AwsClientBuilder.EndpointConfiguration endpointConfig =
-                new AwsClientBuilder.EndpointConfiguration(properties.getEndpoint(), properties.getRegion());
-
-            AWSCredentials credentials = new BasicAWSCredentials(properties.getAccessKey(), properties.getSecretKey());
-            AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(credentials);
-            ClientConfiguration clientConfig = new ClientConfiguration();
-            if (OssConstant.IS_HTTPS.equals(properties.getIsHttps())) {
-                clientConfig.setProtocol(Protocol.HTTPS);
-            } else {
-                clientConfig.setProtocol(Protocol.HTTP);
-            }
-            AmazonS3ClientBuilder build = AmazonS3Client.builder()
-                .withEndpointConfiguration(endpointConfig)
-                .withClientConfiguration(clientConfig)
-                .withCredentials(credentialsProvider)
-                .disableChunkedEncoding();
-            if (!StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE)) {
-                // minio 浣跨敤https闄愬埗浣跨敤鍩熷悕璁块棶 闇�瑕佹閰嶇疆 绔欑偣濉煙鍚�
-                build.enablePathStyleAccess();
-            }
-            this.client = build.build();
-
-            createBucket();
-        } catch (Exception e) {
-            if (e instanceof OssException) {
-                throw e;
-            }
-            throw new OssException("閰嶇疆閿欒! 璇锋鏌ョ郴缁熼厤缃�:[" + e.getMessage() + "]");
-        }
-    }
-
-    public void createBucket() {
-        try {
-            String bucketName = properties.getBucketName();
-            if (client.doesBucketExistV2(bucketName)) {
-                return;
-            }
-            CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
-            AccessPolicyType accessPolicy = getAccessPolicy();
-            createBucketRequest.setCannedAcl(accessPolicy.getAcl());
-            client.createBucket(createBucketRequest);
-            client.setBucketPolicy(bucketName, getPolicy(bucketName, accessPolicy.getPolicyType()));
-        } catch (Exception e) {
-            throw new OssException("鍒涘缓Bucket澶辫触, 璇锋牳瀵归厤缃俊鎭�:[" + e.getMessage() + "]");
-        }
-    }
-
-    public UploadResult upload(byte[] data, String path, String contentType) {
-        return upload(new ByteArrayInputStream(data), path, contentType);
-    }
-
-    public UploadResult upload(InputStream inputStream, String path, String contentType) {
-        if (!(inputStream instanceof ByteArrayInputStream)) {
-            inputStream = new ByteArrayInputStream(IoUtil.readBytes(inputStream));
-        }
-        try {
-            ObjectMetadata metadata = new ObjectMetadata();
-            metadata.setContentType(contentType);
-            metadata.setContentLength(inputStream.available());
-            PutObjectRequest putObjectRequest = new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata);
-            // 璁剧疆涓婁紶瀵硅薄鐨� Acl 涓哄叕鍏辫
-            putObjectRequest.setCannedAcl(getAccessPolicy().getAcl());
-            client.putObject(putObjectRequest);
-        } catch (Exception e) {
-            throw new OssException("涓婁紶鏂囦欢澶辫触锛岃妫�鏌ラ厤缃俊鎭�:[" + e.getMessage() + "]");
-        }
-        return UploadResult.builder().url(getUrl() + "/" + path).filename(path).build();
-    }
-
-    public void delete(String path) {
-        path = path.replace(getUrl() + "/", "");
-        try {
-            client.deleteObject(properties.getBucketName(), path);
-        } catch (Exception e) {
-            throw new OssException("鍒犻櫎鏂囦欢澶辫触锛岃妫�鏌ラ厤缃俊鎭�:[" + e.getMessage() + "]");
-        }
-    }
-
-    public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) {
-        return upload(data, getPath(properties.getPrefix(), suffix), contentType);
-    }
-
-    public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) {
-        return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType);
-    }
-
-    /**
-     * 鑾峰彇鏂囦欢鍏冩暟鎹�
-     *
-     * @param path 瀹屾暣鏂囦欢璺緞
-     */
-    public ObjectMetadata getObjectMetadata(String path) {
-        path = path.replace(getUrl() + "/", "");
-        S3Object object = client.getObject(properties.getBucketName(), path);
-        return object.getObjectMetadata();
-    }
-
-    public InputStream getObjectContent(String path) {
-        path = path.replace(getUrl() + "/", "");
-        S3Object object = client.getObject(properties.getBucketName(), path);
-        return object.getObjectContent();
-    }
-
-    public String getUrl() {
-        String domain = properties.getDomain();
-        String endpoint = properties.getEndpoint();
-        String header = OssConstant.IS_HTTPS.equals(properties.getIsHttps()) ? "https://" : "http://";
-        // 浜戞湇鍔″晢鐩存帴杩斿洖
-        if (StringUtils.containsAny(endpoint, OssConstant.CLOUD_SERVICE)) {
-            if (StringUtils.isNotBlank(domain)) {
-                return header + domain;
-            }
-            return header + properties.getBucketName() + "." + endpoint;
-        }
-        // minio 鍗曠嫭澶勭悊
-        if (StringUtils.isNotBlank(domain)) {
-            return header + domain + "/" + properties.getBucketName();
-        }
-        return header + endpoint + "/" + properties.getBucketName();
-    }
-
-    public String getPath(String prefix, String suffix) {
-        // 鐢熸垚uuid
-        String uuid = IdUtil.fastSimpleUUID();
-        // 鏂囦欢璺緞
-        String path = DateUtils.datePath() + "/" + uuid;
-        if (StringUtils.isNotBlank(prefix)) {
-            path = prefix + "/" + path;
-        }
-        return path + suffix;
-    }
-
-
-    public String getConfigKey() {
-        return configKey;
-    }
-
-    /**
-     * 鑾峰彇绉佹湁URL閾炬帴
-     *
-     * @param objectKey 瀵硅薄KEY
-     * @param second    鎺堟潈鏃堕棿
-     */
-    public String getPrivateUrl(String objectKey, Integer second) {
-        GeneratePresignedUrlRequest generatePresignedUrlRequest =
-            new GeneratePresignedUrlRequest(properties.getBucketName(), objectKey)
-                .withMethod(HttpMethod.GET)
-                .withExpiration(new Date(System.currentTimeMillis() + 1000L * second));
-        URL url = client.generatePresignedUrl(generatePresignedUrlRequest);
-        return url.toString();
-    }
-
-    /**
-     * 妫�鏌ラ厤缃槸鍚︾浉鍚�
-     */
-    public boolean checkPropertiesSame(OssProperties properties) {
-        return this.properties.equals(properties);
-    }
-
-    /**
-     * 鑾峰彇褰撳墠妗舵潈闄愮被鍨�
-     *
-     * @return 褰撳墠妗舵潈闄愮被鍨媍ode
-     */
-    public AccessPolicyType getAccessPolicy() {
-        return AccessPolicyType.getByType(properties.getAccessPolicy());
-    }
-
-    private static String getPolicy(String bucketName, PolicyType policyType) {
-        StringBuilder builder = new StringBuilder();
-        builder.append("{\n\"Statement\": [\n{\n\"Action\": [\n");
-        builder.append(switch (policyType) {
-            case WRITE -> "\"s3:GetBucketLocation\",\n\"s3:ListBucketMultipartUploads\"\n";
-            case READ_WRITE -> "\"s3:GetBucketLocation\",\n\"s3:ListBucket\",\n\"s3:ListBucketMultipartUploads\"\n";
-            default -> "\"s3:GetBucketLocation\"\n";
-        });
-        builder.append("],\n\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
-        builder.append(bucketName);
-        builder.append("\"\n},\n");
-        if (policyType == PolicyType.READ) {
-            builder.append("{\n\"Action\": [\n\"s3:ListBucket\"\n],\n\"Effect\": \"Deny\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
-            builder.append(bucketName);
-            builder.append("\"\n},\n");
-        }
-        builder.append("{\n\"Action\": ");
-        builder.append(switch (policyType) {
-            case WRITE -> "[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n";
-            case READ_WRITE -> "[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:GetObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n";
-            default -> "\"s3:GetObject\",\n";
-        });
-        builder.append("\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
-        builder.append(bucketName);
-        builder.append("/*\"\n}\n],\n\"Version\": \"2012-10-17\"\n}\n");
-        return builder.toString();
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/entity/UploadResult.java b/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/entity/UploadResult.java
deleted file mode 100644
index fd2e7fc..0000000
--- a/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/entity/UploadResult.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.ruoyi.common.oss.entity;
-
-import lombok.Builder;
-import lombok.Data;
-
-/**
- * 涓婁紶杩斿洖浣�
- *
- * @author Lion Li
- */
-@Data
-@Builder
-public class UploadResult {
-
-    /**
-     * 鏂囦欢璺緞
-     */
-    private String url;
-
-    /**
-     * 鏂囦欢鍚�
-     */
-    private String filename;
-}
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/enumd/AccessPolicyType.java b/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/enumd/AccessPolicyType.java
deleted file mode 100644
index 140f67a..0000000
--- a/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/enumd/AccessPolicyType.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.ruoyi.common.oss.enumd;
-
-import com.amazonaws.services.s3.model.CannedAccessControlList;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 妗惰闂瓥鐣ラ厤缃�
- *
- * @author 闄堣碀
- */
-@Getter
-@AllArgsConstructor
-public enum AccessPolicyType {
-
-    /**
-     * private
-     */
-    PRIVATE("0", CannedAccessControlList.Private, PolicyType.WRITE),
-
-    /**
-     * public
-     */
-    PUBLIC("1", CannedAccessControlList.PublicRead, PolicyType.READ),
-
-    /**
-     * custom
-     */
-    CUSTOM("2",CannedAccessControlList.PublicRead, PolicyType.READ);
-
-    /**
-     * 妗� 鏉冮檺绫诲瀷
-     */
-    private final String type;
-
-    /**
-     * 鏂囦欢瀵硅薄 鏉冮檺绫诲瀷
-     */
-    private final CannedAccessControlList acl;
-
-    /**
-     * 妗剁瓥鐣ョ被鍨�
-     */
-    private final PolicyType policyType;
-
-    public static AccessPolicyType getByType(String type) {
-        for (AccessPolicyType value : values()) {
-            if (value.getType().equals(type)) {
-                return value;
-            }
-        }
-        throw new RuntimeException("'type' not found By " + type);
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/enumd/PolicyType.java b/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/enumd/PolicyType.java
deleted file mode 100644
index c019d3b..0000000
--- a/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/enumd/PolicyType.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.ruoyi.common.oss.enumd;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * minio绛栫暐閰嶇疆
- *
- * @author Lion Li
- */
-@Getter
-@AllArgsConstructor
-public enum PolicyType {
-
-    /**
-     * 鍙
-     */
-    READ("read-only"),
-
-    /**
-     * 鍙啓
-     */
-    WRITE("write-only"),
-
-    /**
-     * 璇诲啓
-     */
-    READ_WRITE("read-write");
-
-    /**
-     * 绫诲瀷
-     */
-    private final String type;
-
-}
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/exception/OssException.java b/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/exception/OssException.java
deleted file mode 100644
index cfc7520..0000000
--- a/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/exception/OssException.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.ruoyi.common.oss.exception;
-
-import java.io.Serial;
-
-/**
- * OSS寮傚父绫�
- *
- * @author Lion Li
- */
-public class OssException extends RuntimeException {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    public OssException(String msg) {
-        super(msg);
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/factory/OssFactory.java b/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/factory/OssFactory.java
deleted file mode 100644
index 82467ef..0000000
--- a/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/factory/OssFactory.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package com.ruoyi.common.oss.factory;
-
-import com.ruoyi.common.core.constant.CacheNames;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.json.utils.JsonUtils;
-import com.ruoyi.common.oss.constant.OssConstant;
-import com.ruoyi.common.oss.core.OssClient;
-import com.ruoyi.common.oss.exception.OssException;
-import com.ruoyi.common.oss.properties.OssProperties;
-import com.ruoyi.common.redis.utils.CacheUtils;
-import com.ruoyi.common.redis.utils.RedisUtils;
-import lombok.extern.slf4j.Slf4j;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * 鏂囦欢涓婁紶Factory
- *
- * @author Lion Li
- */
-@Slf4j
-public class OssFactory {
-
-    private static final Map<String, OssClient> CLIENT_CACHE = new ConcurrentHashMap<>();
-
-    /**
-     * 鑾峰彇榛樿瀹炰緥
-     */
-    public static OssClient instance() {
-        // 鑾峰彇redis 榛樿绫诲瀷
-        String configKey = RedisUtils.getCacheObject(OssConstant.DEFAULT_CONFIG_KEY);
-        if (StringUtils.isEmpty(configKey)) {
-            throw new OssException("鏂囦欢瀛樺偍鏈嶅姟绫诲瀷鏃犳硶鎵惧埌!");
-        }
-        return instance(configKey);
-    }
-
-    /**
-     * 鏍规嵁绫诲瀷鑾峰彇瀹炰緥
-     */
-    public static OssClient instance(String configKey) {
-        String json = CacheUtils.get(CacheNames.SYS_OSS_CONFIG, configKey);
-        if (json == null) {
-            throw new OssException("绯荤粺寮傚父, '" + configKey + "'閰嶇疆淇℃伅涓嶅瓨鍦�!");
-        }
-        OssProperties properties = JsonUtils.parseObject(json, OssProperties.class);
-        OssClient client = CLIENT_CACHE.get(configKey);
-        if (client == null) {
-            CLIENT_CACHE.put(configKey, new OssClient(configKey, properties));
-            log.info("鍒涘缓OSS瀹炰緥 key => {}", configKey);
-            return CLIENT_CACHE.get(configKey);
-        }
-        // 閰嶇疆涓嶇浉鍚屽垯閲嶆柊鏋勫缓
-        if (!client.checkPropertiesSame(properties)) {
-            CLIENT_CACHE.put(configKey, new OssClient(configKey, properties));
-            log.info("閲嶈浇OSS瀹炰緥 key => {}", configKey);
-            return CLIENT_CACHE.get(configKey);
-        }
-        return client;
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/properties/OssProperties.java b/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/properties/OssProperties.java
deleted file mode 100644
index bf7ab2f..0000000
--- a/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/properties/OssProperties.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package com.ruoyi.common.oss.properties;
-
-import lombok.Data;
-
-/**
- * OSS瀵硅薄瀛樺偍 閰嶇疆灞炴��
- *
- * @author Lion Li
- */
-@Data
-public class OssProperties {
-
-    /**
-     * 璁块棶绔欑偣
-     */
-    private String endpoint;
-
-    /**
-     * 鑷畾涔夊煙鍚�
-     */
-    private String domain;
-
-    /**
-     * 鍓嶇紑
-     */
-    private String prefix;
-
-    /**
-     * ACCESS_KEY
-     */
-    private String accessKey;
-
-    /**
-     * SECRET_KEY
-     */
-    private String secretKey;
-
-    /**
-     * 瀛樺偍绌洪棿鍚�
-     */
-    private String bucketName;
-
-    /**
-     * 瀛樺偍鍖哄煙
-     */
-    private String region;
-
-    /**
-     * 鏄惁https锛圷=鏄�,N=鍚︼級
-     */
-    private String isHttps;
-
-    /**
-     * 妗舵潈闄愮被鍨�(0private 1public 2custom)
-     */
-    private String accessPolicy;
-
-}
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/constant/OssConstant.java b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/constant/OssConstant.java
new file mode 100644
index 0000000..417f17b
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/constant/OssConstant.java
@@ -0,0 +1,38 @@
+package org.dromara.common.oss.constant;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 瀵硅薄瀛樺偍甯搁噺
+ *
+ * @author Lion Li
+ */
+public interface OssConstant {
+
+    /**
+     * 榛樿閰嶇疆KEY
+     */
+    String DEFAULT_CONFIG_KEY = "sys_oss:default_config";
+
+    /**
+     * 棰勮鍒楄〃璧勬簮寮�鍏矺ey
+     */
+    String PEREVIEW_LIST_RESOURCE_KEY = "sys.oss.previewListResource";
+
+    /**
+     * 绯荤粺鏁版嵁ids
+     */
+    List<Long> SYSTEM_DATA_IDS = Arrays.asList(1L, 2L, 3L, 4L);
+
+    /**
+     * 浜戞湇鍔″晢
+     */
+    String[] CLOUD_SERVICE = new String[] {"aliyun", "qcloud", "qiniu", "obs"};
+
+    /**
+     * https 鐘舵��
+     */
+    String IS_HTTPS = "Y";
+
+}
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java
new file mode 100644
index 0000000..992e3d4
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java
@@ -0,0 +1,245 @@
+package org.dromara.common.oss.core;
+
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.IdUtil;
+import com.amazonaws.ClientConfiguration;
+import com.amazonaws.HttpMethod;
+import com.amazonaws.Protocol;
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.AWSCredentialsProvider;
+import com.amazonaws.auth.AWSStaticCredentialsProvider;
+import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.client.builder.AwsClientBuilder;
+import com.amazonaws.services.s3.AmazonS3;
+import com.amazonaws.services.s3.AmazonS3Client;
+import com.amazonaws.services.s3.AmazonS3ClientBuilder;
+import com.amazonaws.services.s3.model.*;
+import org.dromara.common.core.utils.DateUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.oss.constant.OssConstant;
+import org.dromara.common.oss.entity.UploadResult;
+import org.dromara.common.oss.enumd.AccessPolicyType;
+import org.dromara.common.oss.enumd.PolicyType;
+import org.dromara.common.oss.exception.OssException;
+import org.dromara.common.oss.properties.OssProperties;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Date;
+
+/**
+ * S3 瀛樺偍鍗忚 鎵�鏈夊吋瀹筍3鍗忚鐨勪簯鍘傚晢鍧囨敮鎸�
+ * 闃块噷浜� 鑵捐浜� 涓冪墰浜� minio
+ *
+ * @author Lion Li
+ */
+public class OssClient {
+
+    private final String configKey;
+
+    private final OssProperties properties;
+
+    private final AmazonS3 client;
+
+    public OssClient(String configKey, OssProperties ossProperties) {
+        this.configKey = configKey;
+        this.properties = ossProperties;
+        try {
+            AwsClientBuilder.EndpointConfiguration endpointConfig =
+                new AwsClientBuilder.EndpointConfiguration(properties.getEndpoint(), properties.getRegion());
+
+            AWSCredentials credentials = new BasicAWSCredentials(properties.getAccessKey(), properties.getSecretKey());
+            AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(credentials);
+            ClientConfiguration clientConfig = new ClientConfiguration();
+            if (OssConstant.IS_HTTPS.equals(properties.getIsHttps())) {
+                clientConfig.setProtocol(Protocol.HTTPS);
+            } else {
+                clientConfig.setProtocol(Protocol.HTTP);
+            }
+            AmazonS3ClientBuilder build = AmazonS3Client.builder()
+                .withEndpointConfiguration(endpointConfig)
+                .withClientConfiguration(clientConfig)
+                .withCredentials(credentialsProvider)
+                .disableChunkedEncoding();
+            if (!StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE)) {
+                // minio 浣跨敤https闄愬埗浣跨敤鍩熷悕璁块棶 闇�瑕佹閰嶇疆 绔欑偣濉煙鍚�
+                build.enablePathStyleAccess();
+            }
+            this.client = build.build();
+
+            createBucket();
+        } catch (Exception e) {
+            if (e instanceof OssException) {
+                throw e;
+            }
+            throw new OssException("閰嶇疆閿欒! 璇锋鏌ョ郴缁熼厤缃�:[" + e.getMessage() + "]");
+        }
+    }
+
+    public void createBucket() {
+        try {
+            String bucketName = properties.getBucketName();
+            if (client.doesBucketExistV2(bucketName)) {
+                return;
+            }
+            CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
+            AccessPolicyType accessPolicy = getAccessPolicy();
+            createBucketRequest.setCannedAcl(accessPolicy.getAcl());
+            client.createBucket(createBucketRequest);
+            client.setBucketPolicy(bucketName, getPolicy(bucketName, accessPolicy.getPolicyType()));
+        } catch (Exception e) {
+            throw new OssException("鍒涘缓Bucket澶辫触, 璇锋牳瀵归厤缃俊鎭�:[" + e.getMessage() + "]");
+        }
+    }
+
+    public UploadResult upload(byte[] data, String path, String contentType) {
+        return upload(new ByteArrayInputStream(data), path, contentType);
+    }
+
+    public UploadResult upload(InputStream inputStream, String path, String contentType) {
+        if (!(inputStream instanceof ByteArrayInputStream)) {
+            inputStream = new ByteArrayInputStream(IoUtil.readBytes(inputStream));
+        }
+        try {
+            ObjectMetadata metadata = new ObjectMetadata();
+            metadata.setContentType(contentType);
+            metadata.setContentLength(inputStream.available());
+            PutObjectRequest putObjectRequest = new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata);
+            // 璁剧疆涓婁紶瀵硅薄鐨� Acl 涓哄叕鍏辫
+            putObjectRequest.setCannedAcl(getAccessPolicy().getAcl());
+            client.putObject(putObjectRequest);
+        } catch (Exception e) {
+            throw new OssException("涓婁紶鏂囦欢澶辫触锛岃妫�鏌ラ厤缃俊鎭�:[" + e.getMessage() + "]");
+        }
+        return UploadResult.builder().url(getUrl() + "/" + path).filename(path).build();
+    }
+
+    public void delete(String path) {
+        path = path.replace(getUrl() + "/", "");
+        try {
+            client.deleteObject(properties.getBucketName(), path);
+        } catch (Exception e) {
+            throw new OssException("鍒犻櫎鏂囦欢澶辫触锛岃妫�鏌ラ厤缃俊鎭�:[" + e.getMessage() + "]");
+        }
+    }
+
+    public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) {
+        return upload(data, getPath(properties.getPrefix(), suffix), contentType);
+    }
+
+    public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) {
+        return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType);
+    }
+
+    /**
+     * 鑾峰彇鏂囦欢鍏冩暟鎹�
+     *
+     * @param path 瀹屾暣鏂囦欢璺緞
+     */
+    public ObjectMetadata getObjectMetadata(String path) {
+        path = path.replace(getUrl() + "/", "");
+        S3Object object = client.getObject(properties.getBucketName(), path);
+        return object.getObjectMetadata();
+    }
+
+    public InputStream getObjectContent(String path) {
+        path = path.replace(getUrl() + "/", "");
+        S3Object object = client.getObject(properties.getBucketName(), path);
+        return object.getObjectContent();
+    }
+
+    public String getUrl() {
+        String domain = properties.getDomain();
+        String endpoint = properties.getEndpoint();
+        String header = OssConstant.IS_HTTPS.equals(properties.getIsHttps()) ? "https://" : "http://";
+        // 浜戞湇鍔″晢鐩存帴杩斿洖
+        if (StringUtils.containsAny(endpoint, OssConstant.CLOUD_SERVICE)) {
+            if (StringUtils.isNotBlank(domain)) {
+                return header + domain;
+            }
+            return header + properties.getBucketName() + "." + endpoint;
+        }
+        // minio 鍗曠嫭澶勭悊
+        if (StringUtils.isNotBlank(domain)) {
+            return header + domain + "/" + properties.getBucketName();
+        }
+        return header + endpoint + "/" + properties.getBucketName();
+    }
+
+    public String getPath(String prefix, String suffix) {
+        // 鐢熸垚uuid
+        String uuid = IdUtil.fastSimpleUUID();
+        // 鏂囦欢璺緞
+        String path = DateUtils.datePath() + "/" + uuid;
+        if (StringUtils.isNotBlank(prefix)) {
+            path = prefix + "/" + path;
+        }
+        return path + suffix;
+    }
+
+
+    public String getConfigKey() {
+        return configKey;
+    }
+
+    /**
+     * 鑾峰彇绉佹湁URL閾炬帴
+     *
+     * @param objectKey 瀵硅薄KEY
+     * @param second    鎺堟潈鏃堕棿
+     */
+    public String getPrivateUrl(String objectKey, Integer second) {
+        GeneratePresignedUrlRequest generatePresignedUrlRequest =
+            new GeneratePresignedUrlRequest(properties.getBucketName(), objectKey)
+                .withMethod(HttpMethod.GET)
+                .withExpiration(new Date(System.currentTimeMillis() + 1000L * second));
+        URL url = client.generatePresignedUrl(generatePresignedUrlRequest);
+        return url.toString();
+    }
+
+    /**
+     * 妫�鏌ラ厤缃槸鍚︾浉鍚�
+     */
+    public boolean checkPropertiesSame(OssProperties properties) {
+        return this.properties.equals(properties);
+    }
+
+    /**
+     * 鑾峰彇褰撳墠妗舵潈闄愮被鍨�
+     *
+     * @return 褰撳墠妗舵潈闄愮被鍨媍ode
+     */
+    public AccessPolicyType getAccessPolicy() {
+        return AccessPolicyType.getByType(properties.getAccessPolicy());
+    }
+
+    private static String getPolicy(String bucketName, PolicyType policyType) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("{\n\"Statement\": [\n{\n\"Action\": [\n");
+        builder.append(switch (policyType) {
+            case WRITE -> "\"s3:GetBucketLocation\",\n\"s3:ListBucketMultipartUploads\"\n";
+            case READ_WRITE -> "\"s3:GetBucketLocation\",\n\"s3:ListBucket\",\n\"s3:ListBucketMultipartUploads\"\n";
+            default -> "\"s3:GetBucketLocation\"\n";
+        });
+        builder.append("],\n\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
+        builder.append(bucketName);
+        builder.append("\"\n},\n");
+        if (policyType == PolicyType.READ) {
+            builder.append("{\n\"Action\": [\n\"s3:ListBucket\"\n],\n\"Effect\": \"Deny\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
+            builder.append(bucketName);
+            builder.append("\"\n},\n");
+        }
+        builder.append("{\n\"Action\": ");
+        builder.append(switch (policyType) {
+            case WRITE -> "[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n";
+            case READ_WRITE -> "[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:GetObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n";
+            default -> "\"s3:GetObject\",\n";
+        });
+        builder.append("\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
+        builder.append(bucketName);
+        builder.append("/*\"\n}\n],\n\"Version\": \"2012-10-17\"\n}\n");
+        return builder.toString();
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/entity/UploadResult.java b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/entity/UploadResult.java
new file mode 100644
index 0000000..a6f57e5
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/entity/UploadResult.java
@@ -0,0 +1,24 @@
+package org.dromara.common.oss.entity;
+
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * 涓婁紶杩斿洖浣�
+ *
+ * @author Lion Li
+ */
+@Data
+@Builder
+public class UploadResult {
+
+    /**
+     * 鏂囦欢璺緞
+     */
+    private String url;
+
+    /**
+     * 鏂囦欢鍚�
+     */
+    private String filename;
+}
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/enumd/AccessPolicyType.java b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/enumd/AccessPolicyType.java
new file mode 100644
index 0000000..9074d72
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/enumd/AccessPolicyType.java
@@ -0,0 +1,55 @@
+package org.dromara.common.oss.enumd;
+
+import com.amazonaws.services.s3.model.CannedAccessControlList;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 妗惰闂瓥鐣ラ厤缃�
+ *
+ * @author 闄堣碀
+ */
+@Getter
+@AllArgsConstructor
+public enum AccessPolicyType {
+
+    /**
+     * private
+     */
+    PRIVATE("0", CannedAccessControlList.Private, PolicyType.WRITE),
+
+    /**
+     * public
+     */
+    PUBLIC("1", CannedAccessControlList.PublicRead, PolicyType.READ),
+
+    /**
+     * custom
+     */
+    CUSTOM("2",CannedAccessControlList.PublicRead, PolicyType.READ);
+
+    /**
+     * 妗� 鏉冮檺绫诲瀷
+     */
+    private final String type;
+
+    /**
+     * 鏂囦欢瀵硅薄 鏉冮檺绫诲瀷
+     */
+    private final CannedAccessControlList acl;
+
+    /**
+     * 妗剁瓥鐣ョ被鍨�
+     */
+    private final PolicyType policyType;
+
+    public static AccessPolicyType getByType(String type) {
+        for (AccessPolicyType value : values()) {
+            if (value.getType().equals(type)) {
+                return value;
+            }
+        }
+        throw new RuntimeException("'type' not found By " + type);
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/enumd/PolicyType.java b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/enumd/PolicyType.java
new file mode 100644
index 0000000..fe96341
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/enumd/PolicyType.java
@@ -0,0 +1,35 @@
+package org.dromara.common.oss.enumd;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * minio绛栫暐閰嶇疆
+ *
+ * @author Lion Li
+ */
+@Getter
+@AllArgsConstructor
+public enum PolicyType {
+
+    /**
+     * 鍙
+     */
+    READ("read-only"),
+
+    /**
+     * 鍙啓
+     */
+    WRITE("write-only"),
+
+    /**
+     * 璇诲啓
+     */
+    READ_WRITE("read-write");
+
+    /**
+     * 绫诲瀷
+     */
+    private final String type;
+
+}
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/exception/OssException.java b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/exception/OssException.java
new file mode 100644
index 0000000..52e9623
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/exception/OssException.java
@@ -0,0 +1,19 @@
+package org.dromara.common.oss.exception;
+
+import java.io.Serial;
+
+/**
+ * OSS寮傚父绫�
+ *
+ * @author Lion Li
+ */
+public class OssException extends RuntimeException {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    public OssException(String msg) {
+        super(msg);
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/factory/OssFactory.java b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/factory/OssFactory.java
new file mode 100644
index 0000000..084d89a
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/factory/OssFactory.java
@@ -0,0 +1,63 @@
+package org.dromara.common.oss.factory;
+
+import org.dromara.common.core.constant.CacheNames;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.json.utils.JsonUtils;
+import org.dromara.common.oss.constant.OssConstant;
+import org.dromara.common.oss.core.OssClient;
+import org.dromara.common.oss.exception.OssException;
+import org.dromara.common.oss.properties.OssProperties;
+import org.dromara.common.redis.utils.CacheUtils;
+import org.dromara.common.redis.utils.RedisUtils;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 鏂囦欢涓婁紶Factory
+ *
+ * @author Lion Li
+ */
+@Slf4j
+public class OssFactory {
+
+    private static final Map<String, OssClient> CLIENT_CACHE = new ConcurrentHashMap<>();
+
+    /**
+     * 鑾峰彇榛樿瀹炰緥
+     */
+    public static OssClient instance() {
+        // 鑾峰彇redis 榛樿绫诲瀷
+        String configKey = RedisUtils.getCacheObject(OssConstant.DEFAULT_CONFIG_KEY);
+        if (StringUtils.isEmpty(configKey)) {
+            throw new OssException("鏂囦欢瀛樺偍鏈嶅姟绫诲瀷鏃犳硶鎵惧埌!");
+        }
+        return instance(configKey);
+    }
+
+    /**
+     * 鏍规嵁绫诲瀷鑾峰彇瀹炰緥
+     */
+    public static OssClient instance(String configKey) {
+        String json = CacheUtils.get(CacheNames.SYS_OSS_CONFIG, configKey);
+        if (json == null) {
+            throw new OssException("绯荤粺寮傚父, '" + configKey + "'閰嶇疆淇℃伅涓嶅瓨鍦�!");
+        }
+        OssProperties properties = JsonUtils.parseObject(json, OssProperties.class);
+        OssClient client = CLIENT_CACHE.get(configKey);
+        if (client == null) {
+            CLIENT_CACHE.put(configKey, new OssClient(configKey, properties));
+            log.info("鍒涘缓OSS瀹炰緥 key => {}", configKey);
+            return CLIENT_CACHE.get(configKey);
+        }
+        // 閰嶇疆涓嶇浉鍚屽垯閲嶆柊鏋勫缓
+        if (!client.checkPropertiesSame(properties)) {
+            CLIENT_CACHE.put(configKey, new OssClient(configKey, properties));
+            log.info("閲嶈浇OSS瀹炰緥 key => {}", configKey);
+            return CLIENT_CACHE.get(configKey);
+        }
+        return client;
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/properties/OssProperties.java b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/properties/OssProperties.java
new file mode 100644
index 0000000..697530b
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/properties/OssProperties.java
@@ -0,0 +1,58 @@
+package org.dromara.common.oss.properties;
+
+import lombok.Data;
+
+/**
+ * OSS瀵硅薄瀛樺偍 閰嶇疆灞炴��
+ *
+ * @author Lion Li
+ */
+@Data
+public class OssProperties {
+
+    /**
+     * 璁块棶绔欑偣
+     */
+    private String endpoint;
+
+    /**
+     * 鑷畾涔夊煙鍚�
+     */
+    private String domain;
+
+    /**
+     * 鍓嶇紑
+     */
+    private String prefix;
+
+    /**
+     * ACCESS_KEY
+     */
+    private String accessKey;
+
+    /**
+     * SECRET_KEY
+     */
+    private String secretKey;
+
+    /**
+     * 瀛樺偍绌洪棿鍚�
+     */
+    private String bucketName;
+
+    /**
+     * 瀛樺偍鍖哄煙
+     */
+    private String region;
+
+    /**
+     * 鏄惁https锛圷=鏄�,N=鍚︼級
+     */
+    private String isHttps;
+
+    /**
+     * 妗舵潈闄愮被鍨�(0private 1public 2custom)
+     */
+    private String accessPolicy;
+
+}
diff --git a/ruoyi-common/ruoyi-common-ratelimiter/pom.xml b/ruoyi-common/ruoyi-common-ratelimiter/pom.xml
index d4aa966..9fce843 100644
--- a/ruoyi-common/ruoyi-common-ratelimiter/pom.xml
+++ b/ruoyi-common/ruoyi-common-ratelimiter/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-common</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -18,12 +18,12 @@
 
     <dependencies>
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-core</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-redis</artifactId>
         </dependency>
     </dependencies>
diff --git a/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/com/ruoyi/common/ratelimiter/annotation/RateLimiter.java b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/com/ruoyi/common/ratelimiter/annotation/RateLimiter.java
deleted file mode 100644
index 87a946b..0000000
--- a/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/com/ruoyi/common/ratelimiter/annotation/RateLimiter.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.ruoyi.common.ratelimiter.annotation;
-
-import com.ruoyi.common.ratelimiter.enums.LimitType;
-
-import java.lang.annotation.*;
-
-/**
- * 闄愭祦娉ㄨВ
- *
- * @author Lion Li
- */
-@Target(ElementType.METHOD)
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-public @interface RateLimiter {
-    /**
-     * 闄愭祦key,鏀寔浣跨敤Spring el琛ㄨ揪寮忔潵鍔ㄦ�佽幏鍙栨柟娉曚笂鐨勫弬鏁板��
-     * 鏍煎紡绫讳技浜�  #code.id #{#code}
-     */
-    String key() default "";
-
-    /**
-     * 闄愭祦鏃堕棿,鍗曚綅绉�
-     */
-    int time() default 60;
-
-    /**
-     * 闄愭祦娆℃暟
-     */
-    int count() default 100;
-
-    /**
-     * 闄愭祦绫诲瀷
-     */
-    LimitType limitType() default LimitType.DEFAULT;
-
-    /**
-     * 鎻愮ず娑堟伅 鏀寔鍥介檯鍖� 鏍煎紡涓� {code}
-     */
-    String message() default "{rate.limiter.message}";
-}
diff --git a/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/com/ruoyi/common/ratelimiter/aspectj/RateLimiterAspect.java b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/com/ruoyi/common/ratelimiter/aspectj/RateLimiterAspect.java
deleted file mode 100644
index 844fa24..0000000
--- a/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/com/ruoyi/common/ratelimiter/aspectj/RateLimiterAspect.java
+++ /dev/null
@@ -1,119 +0,0 @@
-package com.ruoyi.common.ratelimiter.aspectj;
-
-import cn.hutool.core.util.ArrayUtil;
-import com.ruoyi.common.core.constant.GlobalConstants;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.utils.MessageUtils;
-import com.ruoyi.common.core.utils.ServletUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.ratelimiter.annotation.RateLimiter;
-import com.ruoyi.common.ratelimiter.enums.LimitType;
-import com.ruoyi.common.redis.utils.RedisUtils;
-import lombok.extern.slf4j.Slf4j;
-import org.aspectj.lang.JoinPoint;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Before;
-import org.aspectj.lang.reflect.MethodSignature;
-import org.redisson.api.RateType;
-import org.springframework.core.DefaultParameterNameDiscoverer;
-import org.springframework.core.ParameterNameDiscoverer;
-import org.springframework.expression.EvaluationContext;
-import org.springframework.expression.ExpressionParser;
-import org.springframework.expression.ParserContext;
-import org.springframework.expression.common.TemplateParserContext;
-import org.springframework.expression.spel.standard.SpelExpressionParser;
-import org.springframework.expression.spel.support.StandardEvaluationContext;
-
-import java.lang.reflect.Method;
-
-/**
- * 闄愭祦澶勭悊
- *
- * @author Lion Li
- */
-@Slf4j
-@Aspect
-public class RateLimiterAspect {
-
-    /**
-     * 瀹氫箟spel琛ㄨ揪寮忚В鏋愬櫒
-     */
-    private final ExpressionParser parser = new SpelExpressionParser();
-    /**
-     * 瀹氫箟spel瑙f瀽妯$増
-     */
-    private final ParserContext parserContext = new TemplateParserContext();
-    /**
-     * 瀹氫箟spel涓婁笅鏂囧璞¤繘琛岃В鏋�
-     */
-    private final EvaluationContext context = new StandardEvaluationContext();
-    /**
-     * 鏂规硶鍙傛暟瑙f瀽鍣�
-     */
-    private final ParameterNameDiscoverer pnd = new DefaultParameterNameDiscoverer();
-
-    @Before("@annotation(rateLimiter)")
-    public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable {
-        int time = rateLimiter.time();
-        int count = rateLimiter.count();
-        String combineKey = getCombineKey(rateLimiter, point);
-        try {
-            RateType rateType = RateType.OVERALL;
-            if (rateLimiter.limitType() == LimitType.CLUSTER) {
-                rateType = RateType.PER_CLIENT;
-            }
-            long number = RedisUtils.rateLimiter(combineKey, rateType, count, time);
-            if (number == -1) {
-                String message = rateLimiter.message();
-                if (StringUtils.startsWith(message, "{") && StringUtils.endsWith(message, "}")) {
-                    message = MessageUtils.message(StringUtils.substring(message, 1, message.length() - 1));
-                }
-                throw new ServiceException(message);
-            }
-            log.info("闄愬埗浠ょ墝 => {}, 鍓╀綑浠ょ墝 => {}, 缂撳瓨key => '{}'", count, number, combineKey);
-        } catch (Exception e) {
-            if (e instanceof ServiceException) {
-                throw e;
-            } else {
-                throw new RuntimeException("鏈嶅姟鍣ㄩ檺娴佸紓甯革紝璇风◢鍊欏啀璇�");
-            }
-        }
-    }
-
-    public String getCombineKey(RateLimiter rateLimiter, JoinPoint point) {
-        String key = rateLimiter.key();
-        // 鑾峰彇鏂规硶(閫氳繃鏂规硶绛惧悕鏉ヨ幏鍙�)
-        MethodSignature signature = (MethodSignature) point.getSignature();
-        Method method = signature.getMethod();
-        Class<?> targetClass = method.getDeclaringClass();
-        // 鍒ゆ柇鏄惁鏄痵pel鏍煎紡
-        if (StringUtils.containsAny(key, "#")) {
-            // 鑾峰彇鍙傛暟鍊�
-            Object[] args = point.getArgs();
-            // 鑾峰彇鏂规硶涓婂弬鏁扮殑鍚嶇О
-            String[] parameterNames = pnd.getParameterNames(method);
-            if (ArrayUtil.isEmpty(parameterNames)) {
-                throw new ServiceException("闄愭祦key瑙f瀽寮傚父!璇疯仈绯荤鐞嗗憳!");
-            }
-            for (int i = 0; i < parameterNames.length; i++) {
-                context.setVariable(parameterNames[i], args[i]);
-            }
-            // 瑙f瀽杩斿洖缁檏ey
-            try {
-                key = parser.parseExpression(key, parserContext).getValue(context, String.class) + ":";
-            } catch (Exception e) {
-                throw new ServiceException("闄愭祦key瑙f瀽寮傚父!璇疯仈绯荤鐞嗗憳!");
-            }
-        }
-        StringBuilder stringBuffer = new StringBuilder(GlobalConstants.RATE_LIMIT_KEY);
-        stringBuffer.append(ServletUtils.getRequest().getRequestURI()).append(":");
-        if (rateLimiter.limitType() == LimitType.IP) {
-            // 鑾峰彇璇锋眰ip
-            stringBuffer.append(ServletUtils.getClientIP()).append(":");
-        } else if (rateLimiter.limitType() == LimitType.CLUSTER) {
-            // 鑾峰彇瀹㈡埛绔疄渚媔d
-            stringBuffer.append(RedisUtils.getClient().getId()).append(":");
-        }
-        return stringBuffer.append(key).toString();
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/com/ruoyi/common/ratelimiter/config/RateLimiterConfig.java b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/com/ruoyi/common/ratelimiter/config/RateLimiterConfig.java
deleted file mode 100644
index f55a1f7..0000000
--- a/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/com/ruoyi/common/ratelimiter/config/RateLimiterConfig.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.ruoyi.common.ratelimiter.config;
-
-import com.ruoyi.common.ratelimiter.aspectj.RateLimiterAspect;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.context.annotation.Bean;
-import org.springframework.data.redis.connection.RedisConfiguration;
-
-/**
- * @author guangxin
- * @date 2023/1/18
- */
-@AutoConfiguration(after = RedisConfiguration.class)
-public class RateLimiterConfig {
-
-    @Bean
-    public RateLimiterAspect rateLimiterAspect() {
-        return new RateLimiterAspect();
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/com/ruoyi/common/ratelimiter/enums/LimitType.java b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/com/ruoyi/common/ratelimiter/enums/LimitType.java
deleted file mode 100644
index 1ff05d1..0000000
--- a/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/com/ruoyi/common/ratelimiter/enums/LimitType.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.ruoyi.common.ratelimiter.enums;
-
-/**
- * 闄愭祦绫诲瀷
- *
- * @author ruoyi
- */
-
-public enum LimitType {
-    /**
-     * 榛樿绛栫暐鍏ㄥ眬闄愭祦
-     */
-    DEFAULT,
-
-    /**
-     * 鏍规嵁璇锋眰鑰匢P杩涜闄愭祦
-     */
-    IP,
-
-    /**
-     * 瀹炰緥闄愭祦(闆嗙兢澶氬悗绔疄渚�)
-     */
-    CLUSTER
-}
diff --git a/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/annotation/RateLimiter.java b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/annotation/RateLimiter.java
new file mode 100644
index 0000000..de09752
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/annotation/RateLimiter.java
@@ -0,0 +1,41 @@
+package org.dromara.common.ratelimiter.annotation;
+
+import org.dromara.common.ratelimiter.enums.LimitType;
+
+import java.lang.annotation.*;
+
+/**
+ * 闄愭祦娉ㄨВ
+ *
+ * @author Lion Li
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface RateLimiter {
+    /**
+     * 闄愭祦key,鏀寔浣跨敤Spring el琛ㄨ揪寮忔潵鍔ㄦ�佽幏鍙栨柟娉曚笂鐨勫弬鏁板��
+     * 鏍煎紡绫讳技浜�  #code.id #{#code}
+     */
+    String key() default "";
+
+    /**
+     * 闄愭祦鏃堕棿,鍗曚綅绉�
+     */
+    int time() default 60;
+
+    /**
+     * 闄愭祦娆℃暟
+     */
+    int count() default 100;
+
+    /**
+     * 闄愭祦绫诲瀷
+     */
+    LimitType limitType() default LimitType.DEFAULT;
+
+    /**
+     * 鎻愮ず娑堟伅 鏀寔鍥介檯鍖� 鏍煎紡涓� {code}
+     */
+    String message() default "{rate.limiter.message}";
+}
diff --git a/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/aspectj/RateLimiterAspect.java b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/aspectj/RateLimiterAspect.java
new file mode 100644
index 0000000..75b32f1
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/aspectj/RateLimiterAspect.java
@@ -0,0 +1,119 @@
+package org.dromara.common.ratelimiter.aspectj;
+
+import cn.hutool.core.util.ArrayUtil;
+import org.dromara.common.core.constant.GlobalConstants;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.MessageUtils;
+import org.dromara.common.core.utils.ServletUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.ratelimiter.annotation.RateLimiter;
+import org.dromara.common.ratelimiter.enums.LimitType;
+import org.dromara.common.redis.utils.RedisUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.redisson.api.RateType;
+import org.springframework.core.DefaultParameterNameDiscoverer;
+import org.springframework.core.ParameterNameDiscoverer;
+import org.springframework.expression.EvaluationContext;
+import org.springframework.expression.ExpressionParser;
+import org.springframework.expression.ParserContext;
+import org.springframework.expression.common.TemplateParserContext;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.expression.spel.support.StandardEvaluationContext;
+
+import java.lang.reflect.Method;
+
+/**
+ * 闄愭祦澶勭悊
+ *
+ * @author Lion Li
+ */
+@Slf4j
+@Aspect
+public class RateLimiterAspect {
+
+    /**
+     * 瀹氫箟spel琛ㄨ揪寮忚В鏋愬櫒
+     */
+    private final ExpressionParser parser = new SpelExpressionParser();
+    /**
+     * 瀹氫箟spel瑙f瀽妯$増
+     */
+    private final ParserContext parserContext = new TemplateParserContext();
+    /**
+     * 瀹氫箟spel涓婁笅鏂囧璞¤繘琛岃В鏋�
+     */
+    private final EvaluationContext context = new StandardEvaluationContext();
+    /**
+     * 鏂规硶鍙傛暟瑙f瀽鍣�
+     */
+    private final ParameterNameDiscoverer pnd = new DefaultParameterNameDiscoverer();
+
+    @Before("@annotation(rateLimiter)")
+    public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable {
+        int time = rateLimiter.time();
+        int count = rateLimiter.count();
+        String combineKey = getCombineKey(rateLimiter, point);
+        try {
+            RateType rateType = RateType.OVERALL;
+            if (rateLimiter.limitType() == LimitType.CLUSTER) {
+                rateType = RateType.PER_CLIENT;
+            }
+            long number = RedisUtils.rateLimiter(combineKey, rateType, count, time);
+            if (number == -1) {
+                String message = rateLimiter.message();
+                if (StringUtils.startsWith(message, "{") && StringUtils.endsWith(message, "}")) {
+                    message = MessageUtils.message(StringUtils.substring(message, 1, message.length() - 1));
+                }
+                throw new ServiceException(message);
+            }
+            log.info("闄愬埗浠ょ墝 => {}, 鍓╀綑浠ょ墝 => {}, 缂撳瓨key => '{}'", count, number, combineKey);
+        } catch (Exception e) {
+            if (e instanceof ServiceException) {
+                throw e;
+            } else {
+                throw new RuntimeException("鏈嶅姟鍣ㄩ檺娴佸紓甯革紝璇风◢鍊欏啀璇�");
+            }
+        }
+    }
+
+    public String getCombineKey(RateLimiter rateLimiter, JoinPoint point) {
+        String key = rateLimiter.key();
+        // 鑾峰彇鏂规硶(閫氳繃鏂规硶绛惧悕鏉ヨ幏鍙�)
+        MethodSignature signature = (MethodSignature) point.getSignature();
+        Method method = signature.getMethod();
+        Class<?> targetClass = method.getDeclaringClass();
+        // 鍒ゆ柇鏄惁鏄痵pel鏍煎紡
+        if (StringUtils.containsAny(key, "#")) {
+            // 鑾峰彇鍙傛暟鍊�
+            Object[] args = point.getArgs();
+            // 鑾峰彇鏂规硶涓婂弬鏁扮殑鍚嶇О
+            String[] parameterNames = pnd.getParameterNames(method);
+            if (ArrayUtil.isEmpty(parameterNames)) {
+                throw new ServiceException("闄愭祦key瑙f瀽寮傚父!璇疯仈绯荤鐞嗗憳!");
+            }
+            for (int i = 0; i < parameterNames.length; i++) {
+                context.setVariable(parameterNames[i], args[i]);
+            }
+            // 瑙f瀽杩斿洖缁檏ey
+            try {
+                key = parser.parseExpression(key, parserContext).getValue(context, String.class) + ":";
+            } catch (Exception e) {
+                throw new ServiceException("闄愭祦key瑙f瀽寮傚父!璇疯仈绯荤鐞嗗憳!");
+            }
+        }
+        StringBuilder stringBuffer = new StringBuilder(GlobalConstants.RATE_LIMIT_KEY);
+        stringBuffer.append(ServletUtils.getRequest().getRequestURI()).append(":");
+        if (rateLimiter.limitType() == LimitType.IP) {
+            // 鑾峰彇璇锋眰ip
+            stringBuffer.append(ServletUtils.getClientIP()).append(":");
+        } else if (rateLimiter.limitType() == LimitType.CLUSTER) {
+            // 鑾峰彇瀹㈡埛绔疄渚媔d
+            stringBuffer.append(RedisUtils.getClient().getId()).append(":");
+        }
+        return stringBuffer.append(key).toString();
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/config/RateLimiterConfig.java b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/config/RateLimiterConfig.java
new file mode 100644
index 0000000..4b7e5b7
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/config/RateLimiterConfig.java
@@ -0,0 +1,20 @@
+package org.dromara.common.ratelimiter.config;
+
+import org.dromara.common.ratelimiter.aspectj.RateLimiterAspect;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.data.redis.connection.RedisConfiguration;
+
+/**
+ * @author guangxin
+ * @date 2023/1/18
+ */
+@AutoConfiguration(after = RedisConfiguration.class)
+public class RateLimiterConfig {
+
+    @Bean
+    public RateLimiterAspect rateLimiterAspect() {
+        return new RateLimiterAspect();
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/enums/LimitType.java b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/enums/LimitType.java
new file mode 100644
index 0000000..b7f059f
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/enums/LimitType.java
@@ -0,0 +1,24 @@
+package org.dromara.common.ratelimiter.enums;
+
+/**
+ * 闄愭祦绫诲瀷
+ *
+ * @author ruoyi
+ */
+
+public enum LimitType {
+    /**
+     * 榛樿绛栫暐鍏ㄥ眬闄愭祦
+     */
+    DEFAULT,
+
+    /**
+     * 鏍规嵁璇锋眰鑰匢P杩涜闄愭祦
+     */
+    IP,
+
+    /**
+     * 瀹炰緥闄愭祦(闆嗙兢澶氬悗绔疄渚�)
+     */
+    CLUSTER
+}
diff --git a/ruoyi-common/ruoyi-common-ratelimiter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-ratelimiter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index 68afe55..3b95432 100644
--- a/ruoyi-common/ruoyi-common-ratelimiter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-common/ruoyi-common-ratelimiter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +1 @@
-com.ruoyi.common.ratelimiter.config.RateLimiterConfig
+org.dromara.common.ratelimiter.config.RateLimiterConfig
diff --git a/ruoyi-common/ruoyi-common-redis/pom.xml b/ruoyi-common/ruoyi-common-redis/pom.xml
index 9e2d9c6..8170b11 100644
--- a/ruoyi-common/ruoyi-common-redis/pom.xml
+++ b/ruoyi-common/ruoyi-common-redis/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-common</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -19,7 +19,7 @@
     <dependencies>
         <!-- RuoYi Common Core-->
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-core</artifactId>
         </dependency>
 
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/config/RedisConfig.java b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/config/RedisConfig.java
deleted file mode 100644
index 1cbb6eb..0000000
--- a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/config/RedisConfig.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package com.ruoyi.common.redis.config;
-
-import cn.hutool.core.util.ObjectUtil;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.ruoyi.common.redis.config.properties.RedissonProperties;
-import com.ruoyi.common.redis.handler.KeyPrefixHandler;
-import com.ruoyi.common.redis.manager.PlusSpringCacheManager;
-import lombok.extern.slf4j.Slf4j;
-import org.redisson.codec.JsonJacksonCodec;
-import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.cache.CacheManager;
-import org.springframework.cache.annotation.EnableCaching;
-import org.springframework.context.annotation.Bean;
-
-/**
- * redis閰嶇疆
- *
- * @author Lion Li
- */
-@Slf4j
-@AutoConfiguration
-@EnableCaching
-@EnableConfigurationProperties(RedissonProperties.class)
-public class RedisConfig {
-
-    @Autowired
-    private RedissonProperties redissonProperties;
-
-    @Autowired
-    private ObjectMapper objectMapper;
-
-    @Bean
-    public RedissonAutoConfigurationCustomizer redissonCustomizer() {
-        return config -> {
-            config.setThreads(redissonProperties.getThreads())
-                .setNettyThreads(redissonProperties.getNettyThreads())
-                .setCodec(new JsonJacksonCodec(objectMapper));
-            RedissonProperties.SingleServerConfig singleServerConfig = redissonProperties.getSingleServerConfig();
-            if (ObjectUtil.isNotNull(singleServerConfig)) {
-                // 浣跨敤鍗曟満妯″紡
-                config.useSingleServer()
-                    //璁剧疆redis key鍓嶇紑
-                    .setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix()))
-                    .setTimeout(singleServerConfig.getTimeout())
-                    .setClientName(singleServerConfig.getClientName())
-                    .setIdleConnectionTimeout(singleServerConfig.getIdleConnectionTimeout())
-                    .setSubscriptionConnectionPoolSize(singleServerConfig.getSubscriptionConnectionPoolSize())
-                    .setConnectionMinimumIdleSize(singleServerConfig.getConnectionMinimumIdleSize())
-                    .setConnectionPoolSize(singleServerConfig.getConnectionPoolSize());
-            }
-            // 闆嗙兢閰嶇疆鏂瑰紡 鍙傝�冧笅鏂规敞閲�
-            RedissonProperties.ClusterServersConfig clusterServersConfig = redissonProperties.getClusterServersConfig();
-            if (ObjectUtil.isNotNull(clusterServersConfig)) {
-                config.useClusterServers()
-                    //璁剧疆redis key鍓嶇紑
-                    .setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix()))
-                    .setTimeout(clusterServersConfig.getTimeout())
-                    .setClientName(clusterServersConfig.getClientName())
-                    .setIdleConnectionTimeout(clusterServersConfig.getIdleConnectionTimeout())
-                    .setSubscriptionConnectionPoolSize(clusterServersConfig.getSubscriptionConnectionPoolSize())
-                    .setMasterConnectionMinimumIdleSize(clusterServersConfig.getMasterConnectionMinimumIdleSize())
-                    .setMasterConnectionPoolSize(clusterServersConfig.getMasterConnectionPoolSize())
-                    .setSlaveConnectionMinimumIdleSize(clusterServersConfig.getSlaveConnectionMinimumIdleSize())
-                    .setSlaveConnectionPoolSize(clusterServersConfig.getSlaveConnectionPoolSize())
-                    .setReadMode(clusterServersConfig.getReadMode())
-                    .setSubscriptionMode(clusterServersConfig.getSubscriptionMode());
-            }
-            log.info("鍒濆鍖� redis 閰嶇疆");
-        };
-    }
-
-    /**
-     * 鑷畾涔夌紦瀛樼鐞嗗櫒 鏁村悎spring-cache
-     */
-    @Bean
-    public CacheManager cacheManager() {
-        return new PlusSpringCacheManager();
-    }
-
-    /**
-     * redis闆嗙兢閰嶇疆 yml
-     *
-     * --- # redis 闆嗙兢閰嶇疆(鍗曟満涓庨泦缇ゅ彧鑳藉紑鍚竴涓彟涓�涓渶瑕佹敞閲婃帀)
-     * spring:
-     *   redis:
-     *     cluster:
-     *       nodes:
-     *         - 192.168.0.100:6379
-     *         - 192.168.0.101:6379
-     *         - 192.168.0.102:6379
-     *     # 瀵嗙爜
-     *     password:
-     *     # 杩炴帴瓒呮椂鏃堕棿
-     *     timeout: 10s
-     *     # 鏄惁寮�鍚痵sl
-     *     ssl: false
-     *
-     * redisson:
-     *   # 绾跨▼姹犳暟閲�
-     *   threads: 16
-     *   # Netty绾跨▼姹犳暟閲�
-     *   nettyThreads: 32
-     *   # 闆嗙兢閰嶇疆
-     *   clusterServersConfig:
-     *     # 瀹㈡埛绔悕绉�
-     *     clientName: ${ruoyi.name}
-     *     # master鏈�灏忕┖闂茶繛鎺ユ暟
-     *     masterConnectionMinimumIdleSize: 32
-     *     # master杩炴帴姹犲ぇ灏�
-     *     masterConnectionPoolSize: 64
-     *     # slave鏈�灏忕┖闂茶繛鎺ユ暟
-     *     slaveConnectionMinimumIdleSize: 32
-     *     # slave杩炴帴姹犲ぇ灏�
-     *     slaveConnectionPoolSize: 64
-     *     # 杩炴帴绌洪棽瓒呮椂锛屽崟浣嶏細姣
-     *     idleConnectionTimeout: 10000
-     *     # 鍛戒护绛夊緟瓒呮椂锛屽崟浣嶏細姣
-     *     timeout: 3000
-     *     # 鍙戝竷鍜岃闃呰繛鎺ユ睜澶у皬
-     *     subscriptionConnectionPoolSize: 50
-     *     # 璇诲彇妯″紡
-     *     readMode: "SLAVE"
-     *     # 璁㈤槄妯″紡
-     *     subscriptionMode: "MASTER"
-     */
-
-}
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/config/properties/RedissonProperties.java b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/config/properties/RedissonProperties.java
deleted file mode 100644
index c4814d7..0000000
--- a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/config/properties/RedissonProperties.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package com.ruoyi.common.redis.config.properties;
-
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import org.redisson.config.ReadMode;
-import org.redisson.config.SubscriptionMode;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-/**
- * Redisson 閰嶇疆灞炴��
- *
- * @author Lion Li
- */
-@Data
-@ConfigurationProperties(prefix = "redisson")
-public class RedissonProperties {
-
-    /**
-     * redis缂撳瓨key鍓嶇紑
-     */
-    private String keyPrefix;
-
-    /**
-     * 绾跨▼姹犳暟閲�,榛樿鍊� = 褰撳墠澶勭悊鏍告暟閲� * 2
-     */
-    private int threads;
-
-    /**
-     * Netty绾跨▼姹犳暟閲�,榛樿鍊� = 褰撳墠澶勭悊鏍告暟閲� * 2
-     */
-    private int nettyThreads;
-
-    /**
-     * 鍗曟満鏈嶅姟閰嶇疆
-     */
-    private SingleServerConfig singleServerConfig;
-
-    /**
-     * 闆嗙兢鏈嶅姟閰嶇疆
-     */
-    private ClusterServersConfig clusterServersConfig;
-
-    @Data
-    @NoArgsConstructor
-    public static class SingleServerConfig {
-
-        /**
-         * 瀹㈡埛绔悕绉�
-         */
-        private String clientName;
-
-        /**
-         * 鏈�灏忕┖闂茶繛鎺ユ暟
-         */
-        private int connectionMinimumIdleSize;
-
-        /**
-         * 杩炴帴姹犲ぇ灏�
-         */
-        private int connectionPoolSize;
-
-        /**
-         * 杩炴帴绌洪棽瓒呮椂锛屽崟浣嶏細姣
-         */
-        private int idleConnectionTimeout;
-
-        /**
-         * 鍛戒护绛夊緟瓒呮椂锛屽崟浣嶏細姣
-         */
-        private int timeout;
-
-        /**
-         * 鍙戝竷鍜岃闃呰繛鎺ユ睜澶у皬
-         */
-        private int subscriptionConnectionPoolSize;
-
-    }
-
-    @Data
-    @NoArgsConstructor
-    public static class ClusterServersConfig {
-
-        /**
-         * 瀹㈡埛绔悕绉�
-         */
-        private String clientName;
-
-        /**
-         * master鏈�灏忕┖闂茶繛鎺ユ暟
-         */
-        private int masterConnectionMinimumIdleSize;
-
-        /**
-         * master杩炴帴姹犲ぇ灏�
-         */
-        private int masterConnectionPoolSize;
-
-        /**
-         * slave鏈�灏忕┖闂茶繛鎺ユ暟
-         */
-        private int slaveConnectionMinimumIdleSize;
-
-        /**
-         * slave杩炴帴姹犲ぇ灏�
-         */
-        private int slaveConnectionPoolSize;
-
-        /**
-         * 杩炴帴绌洪棽瓒呮椂锛屽崟浣嶏細姣
-         */
-        private int idleConnectionTimeout;
-
-        /**
-         * 鍛戒护绛夊緟瓒呮椂锛屽崟浣嶏細姣
-         */
-        private int timeout;
-
-        /**
-         * 鍙戝竷鍜岃闃呰繛鎺ユ睜澶у皬
-         */
-        private int subscriptionConnectionPoolSize;
-
-        /**
-         * 璇诲彇妯″紡
-         */
-        private ReadMode readMode;
-
-        /**
-         * 璁㈤槄妯″紡
-         */
-        private SubscriptionMode subscriptionMode;
-
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/handler/KeyPrefixHandler.java b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/handler/KeyPrefixHandler.java
deleted file mode 100644
index ff1dbba..0000000
--- a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/handler/KeyPrefixHandler.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.ruoyi.common.redis.handler;
-
-import com.ruoyi.common.core.utils.StringUtils;
-import org.redisson.api.NameMapper;
-
-/**
- * redis缂撳瓨key鍓嶇紑澶勭悊
- *
- * @author ye
- * @date 2022/7/14 17:44
- * @since 4.3.0
- */
-public class KeyPrefixHandler implements NameMapper {
-
-    private final String keyPrefix;
-
-    public KeyPrefixHandler(String keyPrefix) {
-        //鍓嶇紑涓虹┖ 鍒欒繑鍥炵┖鍓嶇紑
-        this.keyPrefix = StringUtils.isBlank(keyPrefix) ? "" : keyPrefix + ":";
-    }
-
-    /**
-     * 澧炲姞鍓嶇紑
-     */
-    @Override
-    public String map(String name) {
-        if (StringUtils.isBlank(name)) {
-            return null;
-        }
-        if (StringUtils.isNotBlank(keyPrefix) && !name.startsWith(keyPrefix)) {
-            return keyPrefix + name;
-        }
-        return name;
-    }
-
-    /**
-     * 鍘婚櫎鍓嶇紑
-     */
-    @Override
-    public String unmap(String name) {
-        if (StringUtils.isBlank(name)) {
-            return null;
-        }
-        if (StringUtils.isNotBlank(keyPrefix) && name.startsWith(keyPrefix)) {
-            return name.substring(keyPrefix.length());
-        }
-        return name;
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/manager/PlusSpringCacheManager.java b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/manager/PlusSpringCacheManager.java
deleted file mode 100644
index 736f0da..0000000
--- a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/manager/PlusSpringCacheManager.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/**
- * Copyright (c) 2013-2021 Nikita Koksharov
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.ruoyi.common.redis.manager;
-
-import com.ruoyi.common.redis.utils.RedisUtils;
-import org.redisson.api.RMap;
-import org.redisson.api.RMapCache;
-import org.redisson.spring.cache.CacheConfig;
-import org.redisson.spring.cache.RedissonCache;
-import org.springframework.boot.convert.DurationStyle;
-import org.springframework.cache.Cache;
-import org.springframework.cache.CacheManager;
-import org.springframework.cache.transaction.TransactionAwareCacheDecorator;
-import org.springframework.util.StringUtils;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-/**
- * A {@link org.springframework.cache.CacheManager} implementation
- * backed by Redisson instance.
- * <p>
- * 淇敼 RedissonSpringCacheManager 婧愮爜
- * 閲嶅啓 cacheName 澶勭悊鏂规硶 鏀寔澶氬弬鏁�
- *
- * @author Nikita Koksharov
- *
- */
-@SuppressWarnings("unchecked")
-public class PlusSpringCacheManager implements CacheManager {
-
-    private boolean dynamic = true;
-
-    private boolean allowNullValues = true;
-
-    private boolean transactionAware = true;
-
-    Map<String, CacheConfig> configMap = new ConcurrentHashMap<>();
-    ConcurrentMap<String, Cache> instanceMap = new ConcurrentHashMap<>();
-
-    /**
-     * Creates CacheManager supplied by Redisson instance
-     */
-    public PlusSpringCacheManager() {
-    }
-
-
-    /**
-     * Defines possibility of storing {@code null} values.
-     * <p>
-     * Default is <code>true</code>
-     *
-     * @param allowNullValues stores if <code>true</code>
-     */
-    public void setAllowNullValues(boolean allowNullValues) {
-        this.allowNullValues = allowNullValues;
-    }
-
-    /**
-     * Defines if cache aware of Spring-managed transactions.
-     * If {@code true} put/evict operations are executed only for successful transaction in after-commit phase.
-     * <p>
-     * Default is <code>false</code>
-     *
-     * @param transactionAware cache is transaction aware if <code>true</code>
-     */
-    public void setTransactionAware(boolean transactionAware) {
-        this.transactionAware = transactionAware;
-    }
-
-    /**
-     * Defines 'fixed' cache names.
-     * A new cache instance will not be created in dynamic for non-defined names.
-     * <p>
-     * `null` parameter setups dynamic mode
-     *
-     * @param names of caches
-     */
-    public void setCacheNames(Collection<String> names) {
-        if (names != null) {
-            for (String name : names) {
-                getCache(name);
-            }
-            dynamic = false;
-        } else {
-            dynamic = true;
-        }
-    }
-
-    /**
-     * Set cache config mapped by cache name
-     *
-     * @param config object
-     */
-    public void setConfig(Map<String, ? extends CacheConfig> config) {
-        this.configMap = (Map<String, CacheConfig>) config;
-    }
-
-    protected CacheConfig createDefaultConfig() {
-        return new CacheConfig();
-    }
-
-    @Override
-    public Cache getCache(String name) {
-        Cache cache = instanceMap.get(name);
-        if (cache != null) {
-            return cache;
-        }
-        if (!dynamic) {
-            return cache;
-        }
-
-        CacheConfig config = configMap.get(name);
-        if (config == null) {
-            config = createDefaultConfig();
-            configMap.put(name, config);
-        }
-
-        // 閲嶅啓 cacheName 鏀寔澶氬弬鏁�
-        String[] array = StringUtils.delimitedListToStringArray(name, "#");
-        name = array[0];
-        if (array.length > 1) {
-            config.setTTL(DurationStyle.detectAndParse(array[1]).toMillis());
-        }
-        if (array.length > 2) {
-            config.setMaxIdleTime(DurationStyle.detectAndParse(array[2]).toMillis());
-        }
-        if (array.length > 3) {
-            config.setMaxSize(Integer.parseInt(array[3]));
-        }
-
-        if (config.getMaxIdleTime() == 0 && config.getTTL() == 0 && config.getMaxSize() == 0) {
-            return createMap(name, config);
-        }
-
-        return createMapCache(name, config);
-    }
-
-    private Cache createMap(String name, CacheConfig config) {
-        RMap<Object, Object> map = RedisUtils.getClient().getMap(name);
-
-        Cache cache = new RedissonCache(map, allowNullValues);
-        if (transactionAware) {
-            cache = new TransactionAwareCacheDecorator(cache);
-        }
-        Cache oldCache = instanceMap.putIfAbsent(name, cache);
-        if (oldCache != null) {
-            cache = oldCache;
-        }
-        return cache;
-    }
-
-    private Cache createMapCache(String name, CacheConfig config) {
-        RMapCache<Object, Object> map = RedisUtils.getClient().getMapCache(name);
-
-        Cache cache = new RedissonCache(map, config, allowNullValues);
-        if (transactionAware) {
-            cache = new TransactionAwareCacheDecorator(cache);
-        }
-        Cache oldCache = instanceMap.putIfAbsent(name, cache);
-        if (oldCache != null) {
-            cache = oldCache;
-        } else {
-            map.setMaxSize(config.getMaxSize());
-        }
-        return cache;
-    }
-
-    @Override
-    public Collection<String> getCacheNames() {
-        return Collections.unmodifiableSet(configMap.keySet());
-    }
-
-
-}
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/utils/CacheUtils.java b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/utils/CacheUtils.java
deleted file mode 100644
index e953d03..0000000
--- a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/utils/CacheUtils.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package com.ruoyi.common.redis.utils;
-
-import com.ruoyi.common.core.utils.SpringUtils;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import org.redisson.api.RMap;
-import org.springframework.cache.Cache;
-import org.springframework.cache.CacheManager;
-
-import java.util.Set;
-
-/**
- * 缂撳瓨鎿嶄綔宸ュ叿绫� {@link }
- *
- * @author Michelle.Chung
- * @date 2022/8/13
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-@SuppressWarnings(value = {"unchecked"})
-public class CacheUtils {
-
-    private static final CacheManager CACHE_MANAGER = SpringUtils.getBean(CacheManager.class);
-
-    /**
-     * 鑾峰彇缂撳瓨缁勫唴鎵�鏈夌殑KEY
-     *
-     * @param cacheNames 缂撳瓨缁勫悕绉�
-     */
-    public static Set<Object> keys(String cacheNames) {
-        RMap<Object, Object> rmap = (RMap<Object, Object>) CACHE_MANAGER.getCache(cacheNames).getNativeCache();
-        return rmap.keySet();
-    }
-
-    /**
-     * 鑾峰彇缂撳瓨鍊�
-     *
-     * @param cacheNames 缂撳瓨缁勫悕绉�
-     * @param key        缂撳瓨key
-     */
-    public static <T> T get(String cacheNames, Object key) {
-        Cache.ValueWrapper wrapper = CACHE_MANAGER.getCache(cacheNames).get(key);
-        return wrapper != null ? (T) wrapper.get() : null;
-    }
-
-    /**
-     * 淇濆瓨缂撳瓨鍊�
-     *
-     * @param cacheNames 缂撳瓨缁勫悕绉�
-     * @param key        缂撳瓨key
-     * @param value      缂撳瓨鍊�
-     */
-    public static void put(String cacheNames, Object key, Object value) {
-        CACHE_MANAGER.getCache(cacheNames).put(key, value);
-    }
-
-    /**
-     * 鍒犻櫎缂撳瓨鍊�
-     *
-     * @param cacheNames 缂撳瓨缁勫悕绉�
-     * @param key        缂撳瓨key
-     */
-    public static void evict(String cacheNames, Object key) {
-        CACHE_MANAGER.getCache(cacheNames).evict(key);
-    }
-
-    /**
-     * 娓呯┖缂撳瓨鍊�
-     *
-     * @param cacheNames 缂撳瓨缁勫悕绉�
-     */
-    public static void clear(String cacheNames) {
-        CACHE_MANAGER.getCache(cacheNames).clear();
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/utils/QueueUtils.java b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/utils/QueueUtils.java
deleted file mode 100644
index 81e2105..0000000
--- a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/utils/QueueUtils.java
+++ /dev/null
@@ -1,180 +0,0 @@
-package com.ruoyi.common.redis.utils;
-
-import com.ruoyi.common.core.utils.SpringUtils;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import org.redisson.api.*;
-
-import java.util.concurrent.TimeUnit;
-import java.util.function.Consumer;
-
-/**
- * 鍒嗗竷寮忛槦鍒楀伐鍏�
- * 杞婚噺绾ч槦鍒� 閲嶉噺绾ф暟鎹噺 璇蜂娇鐢� MQ
- * 瑕佹眰 redis 5.X 浠ヤ笂
- *
- * @author Lion Li
- * @version 3.6.0 鏂板
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class QueueUtils {
-
-    private static final RedissonClient CLIENT = SpringUtils.getBean(RedissonClient.class);
-
-
-    /**
-     * 鑾峰彇瀹㈡埛绔疄渚�
-     */
-    public static RedissonClient getClient() {
-        return CLIENT;
-    }
-
-    /**
-     * 娣诲姞鏅�氶槦鍒楁暟鎹�
-     *
-     * @param queueName 闃熷垪鍚�
-     * @param data      鏁版嵁
-     */
-    public static <T> boolean addQueueObject(String queueName, T data) {
-        RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
-        return queue.offer(data);
-    }
-
-    /**
-     * 閫氱敤鑾峰彇涓�涓槦鍒楁暟鎹� 娌℃湁鏁版嵁杩斿洖 null(涓嶆敮鎸佸欢杩熼槦鍒�)
-     *
-     * @param queueName 闃熷垪鍚�
-     */
-    public static <T> T getQueueObject(String queueName) {
-        RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
-        return queue.poll();
-    }
-
-    /**
-     * 閫氱敤鍒犻櫎闃熷垪鏁版嵁(涓嶆敮鎸佸欢杩熼槦鍒�)
-     */
-    public static <T> boolean removeQueueObject(String queueName, T data) {
-        RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
-        return queue.remove(data);
-    }
-
-    /**
-     * 閫氱敤閿�姣侀槦鍒� 鎵�鏈夐樆濉炵洃鍚� 鎶ラ敊(涓嶆敮鎸佸欢杩熼槦鍒�)
-     */
-    public static <T> boolean destroyQueue(String queueName) {
-        RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
-        return queue.delete();
-    }
-
-    /**
-     * 娣诲姞寤惰繜闃熷垪鏁版嵁 榛樿姣
-     *
-     * @param queueName 闃熷垪鍚�
-     * @param data      鏁版嵁
-     * @param time      寤惰繜鏃堕棿
-     */
-    public static <T> void addDelayedQueueObject(String queueName, T data, long time) {
-        addDelayedQueueObject(queueName, data, time, TimeUnit.MILLISECONDS);
-    }
-
-    /**
-     * 娣诲姞寤惰繜闃熷垪鏁版嵁
-     *
-     * @param queueName 闃熷垪鍚�
-     * @param data      鏁版嵁
-     * @param time      寤惰繜鏃堕棿
-     * @param timeUnit  鍗曚綅
-     */
-    public static <T> void addDelayedQueueObject(String queueName, T data, long time, TimeUnit timeUnit) {
-        RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
-        RDelayedQueue<T> delayedQueue = CLIENT.getDelayedQueue(queue);
-        delayedQueue.offer(data, time, timeUnit);
-    }
-
-    /**
-     * 鑾峰彇涓�涓欢杩熼槦鍒楁暟鎹� 娌℃湁鏁版嵁杩斿洖 null
-     *
-     * @param queueName 闃熷垪鍚�
-     */
-    public static <T> T getDelayedQueueObject(String queueName) {
-        RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
-        RDelayedQueue<T> delayedQueue = CLIENT.getDelayedQueue(queue);
-        return delayedQueue.poll();
-    }
-
-    /**
-     * 鍒犻櫎寤惰繜闃熷垪鏁版嵁
-     */
-    public static <T> boolean removeDelayedQueueObject(String queueName, T data) {
-        RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
-        RDelayedQueue<T> delayedQueue = CLIENT.getDelayedQueue(queue);
-        return delayedQueue.remove(data);
-    }
-
-    /**
-     * 閿�姣佸欢杩熼槦鍒� 鎵�鏈夐樆濉炵洃鍚� 鎶ラ敊
-     */
-    public static <T> void destroyDelayedQueue(String queueName) {
-        RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
-        RDelayedQueue<T> delayedQueue = CLIENT.getDelayedQueue(queue);
-        delayedQueue.destroy();
-    }
-
-    /**
-     * 娣诲姞浼樺厛闃熷垪鏁版嵁
-     *
-     * @param queueName 闃熷垪鍚�
-     * @param data      鏁版嵁
-     */
-    public static <T> boolean addPriorityQueueObject(String queueName, T data) {
-        RPriorityBlockingQueue<T> priorityBlockingQueue = CLIENT.getPriorityBlockingQueue(queueName);
-        return priorityBlockingQueue.offer(data);
-    }
-
-    /**
-     * 灏濊瘯璁剧疆 鏈夌晫闃熷垪 瀹归噺 鐢ㄤ簬闄愬埗鏁伴噺
-     *
-     * @param queueName 闃熷垪鍚�
-     * @param capacity  瀹归噺
-     */
-    public static <T> boolean trySetBoundedQueueCapacity(String queueName, int capacity) {
-        RBoundedBlockingQueue<T> boundedBlockingQueue = CLIENT.getBoundedBlockingQueue(queueName);
-        return boundedBlockingQueue.trySetCapacity(capacity);
-    }
-
-    /**
-     * 灏濊瘯璁剧疆 鏈夌晫闃熷垪 瀹归噺 鐢ㄤ簬闄愬埗鏁伴噺
-     *
-     * @param queueName 闃熷垪鍚�
-     * @param capacity  瀹归噺
-     * @param destroy   宸插瓨鍦ㄦ槸鍚﹂攢姣�
-     */
-    public static <T> boolean trySetBoundedQueueCapacity(String queueName, int capacity, boolean destroy) {
-        RBoundedBlockingQueue<T> boundedBlockingQueue = CLIENT.getBoundedBlockingQueue(queueName);
-        if (boundedBlockingQueue.isExists() && destroy) {
-            destroyQueue(queueName);
-        }
-        return boundedBlockingQueue.trySetCapacity(capacity);
-    }
-
-    /**
-     * 娣诲姞鏈夌晫闃熷垪鏁版嵁
-     *
-     * @param queueName 闃熷垪鍚�
-     * @param data      鏁版嵁
-     * @return 娣诲姞鎴愬姛 true 宸茶揪鍒扮晫闄� false
-     */
-    public static <T> boolean addBoundedQueueObject(String queueName, T data) {
-        RBoundedBlockingQueue<T> boundedBlockingQueue = CLIENT.getBoundedBlockingQueue(queueName);
-        return boundedBlockingQueue.offer(data);
-    }
-
-    /**
-     * 璁㈤槄闃诲闃熷垪(鍙闃呮墍鏈夊疄鐜扮被 渚嬪: 寤惰繜 浼樺厛 鏈夌晫 绛�)
-     */
-    public static <T> void subscribeBlockingQueue(String queueName, Consumer<T> consumer) {
-        RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
-        queue.subscribeOnElements(consumer);
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/utils/RedisUtils.java b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/utils/RedisUtils.java
deleted file mode 100644
index b665160..0000000
--- a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/utils/RedisUtils.java
+++ /dev/null
@@ -1,462 +0,0 @@
-package com.ruoyi.common.redis.utils;
-
-import com.ruoyi.common.core.utils.SpringUtils;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import org.redisson.api.*;
-
-import java.time.Duration;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.Consumer;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-/**
- * redis 宸ュ叿绫�
- *
- * @author Lion Li
- * @version 3.1.0 鏂板
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-@SuppressWarnings(value = {"unchecked", "rawtypes"})
-public class RedisUtils {
-
-    private static final RedissonClient CLIENT = SpringUtils.getBean(RedissonClient.class);
-
-    /**
-     * 闄愭祦
-     *
-     * @param key          闄愭祦key
-     * @param rateType     闄愭祦绫诲瀷
-     * @param rate         閫熺巼
-     * @param rateInterval 閫熺巼闂撮殧
-     * @return -1 琛ㄧず澶辫触
-     */
-    public static long rateLimiter(String key, RateType rateType, int rate, int rateInterval) {
-        RRateLimiter rateLimiter = CLIENT.getRateLimiter(key);
-        rateLimiter.trySetRate(rateType, rate, rateInterval, RateIntervalUnit.SECONDS);
-        if (rateLimiter.tryAcquire()) {
-            return rateLimiter.availablePermits();
-        } else {
-            return -1L;
-        }
-    }
-
-    /**
-     * 鑾峰彇瀹㈡埛绔疄渚�
-     */
-    public static RedissonClient getClient() {
-        return CLIENT;
-    }
-
-    /**
-     * 鍙戝竷閫氶亾娑堟伅
-     *
-     * @param channelKey 閫氶亾key
-     * @param msg        鍙戦�佹暟鎹�
-     * @param consumer   鑷畾涔夊鐞�
-     */
-    public static <T> void publish(String channelKey, T msg, Consumer<T> consumer) {
-        RTopic topic = CLIENT.getTopic(channelKey);
-        topic.publish(msg);
-        consumer.accept(msg);
-    }
-
-    public static <T> void publish(String channelKey, T msg) {
-        RTopic topic = CLIENT.getTopic(channelKey);
-        topic.publish(msg);
-    }
-
-    /**
-     * 璁㈤槄閫氶亾鎺ユ敹娑堟伅
-     *
-     * @param channelKey 閫氶亾key
-     * @param clazz      娑堟伅绫诲瀷
-     * @param consumer   鑷畾涔夊鐞�
-     */
-    public static <T> void subscribe(String channelKey, Class<T> clazz, Consumer<T> consumer) {
-        RTopic topic = CLIENT.getTopic(channelKey);
-        topic.addListener(clazz, (channel, msg) -> consumer.accept(msg));
-    }
-
-    /**
-     * 缂撳瓨鍩烘湰鐨勫璞★紝Integer銆丼tring銆佸疄浣撶被绛�
-     *
-     * @param key   缂撳瓨鐨勯敭鍊�
-     * @param value 缂撳瓨鐨勫��
-     */
-    public static <T> void setCacheObject(final String key, final T 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<T> bucket = CLIENT.getBucket(key);
-        if (isSaveTtl) {
-            try {
-                bucket.setAndKeepTTL(value);
-            } catch (Exception e) {
-                long timeToLive = bucket.remainTimeToLive();
-                setCacheObject(key, value, Duration.ofMillis(timeToLive));
-            }
-        } else {
-            bucket.set(value);
-        }
-    }
-
-    /**
-     * 缂撳瓨鍩烘湰鐨勫璞★紝Integer銆丼tring銆佸疄浣撶被绛�
-     *
-     * @param key      缂撳瓨鐨勯敭鍊�
-     * @param value    缂撳瓨鐨勫��
-     * @param duration 鏃堕棿
-     */
-    public static <T> void setCacheObject(final String key, final T value, final Duration duration) {
-        RBatch batch = CLIENT.createBatch();
-        RBucketAsync<T> bucket = batch.getBucket(key);
-        bucket.setAsync(value);
-        bucket.expireAsync(duration);
-        batch.execute();
-    }
-
-    /**
-     * 娉ㄥ唽瀵硅薄鐩戝惉鍣�
-     * <p>
-     * key 鐩戝惉鍣ㄩ渶寮�鍚� `notify-keyspace-events` 绛� redis 鐩稿叧閰嶇疆
-     *
-     * @param key      缂撳瓨鐨勯敭鍊�
-     * @param listener 鐩戝惉鍣ㄩ厤缃�
-     */
-    public static <T> void addObjectListener(final String key, final ObjectListener listener) {
-        RBucket<T> result = CLIENT.getBucket(key);
-        result.addListener(listener);
-    }
-
-    /**
-     * 璁剧疆鏈夋晥鏃堕棿
-     *
-     * @param key     Redis閿�
-     * @param timeout 瓒呮椂鏃堕棿
-     * @return true=璁剧疆鎴愬姛锛沠alse=璁剧疆澶辫触
-     */
-    public static boolean expire(final String key, final long timeout) {
-        return expire(key, Duration.ofSeconds(timeout));
-    }
-
-    /**
-     * 璁剧疆鏈夋晥鏃堕棿
-     *
-     * @param key      Redis閿�
-     * @param duration 瓒呮椂鏃堕棿
-     * @return true=璁剧疆鎴愬姛锛沠alse=璁剧疆澶辫触
-     */
-    public static boolean expire(final String key, final Duration duration) {
-        RBucket rBucket = CLIENT.getBucket(key);
-        return rBucket.expire(duration);
-    }
-
-    /**
-     * 鑾峰緱缂撳瓨鐨勫熀鏈璞°��
-     *
-     * @param key 缂撳瓨閿��
-     * @return 缂撳瓨閿�煎搴旂殑鏁版嵁
-     */
-    public static <T> T getCacheObject(final String key) {
-        RBucket<T> rBucket = CLIENT.getBucket(key);
-        return rBucket.get();
-    }
-
-    /**
-     * 鑾峰緱key鍓╀綑瀛樻椿鏃堕棿
-     *
-     * @param key 缂撳瓨閿��
-     * @return 鍓╀綑瀛樻椿鏃堕棿
-     */
-    public static <T> long getTimeToLive(final String key) {
-        RBucket<T> rBucket = CLIENT.getBucket(key);
-        return rBucket.remainTimeToLive();
-    }
-
-    /**
-     * 鍒犻櫎鍗曚釜瀵硅薄
-     *
-     * @param key 缂撳瓨鐨勯敭鍊�
-     */
-    public static boolean deleteObject(final String key) {
-        return CLIENT.getBucket(key).delete();
-    }
-
-    /**
-     * 鍒犻櫎闆嗗悎瀵硅薄
-     *
-     * @param collection 澶氫釜瀵硅薄
-     */
-    public static void deleteObject(final Collection collection) {
-        RBatch batch = CLIENT.createBatch();
-        collection.forEach(t -> {
-            batch.getBucket(t.toString()).deleteAsync();
-        });
-        batch.execute();
-    }
-
-    /**
-     * 妫�鏌ョ紦瀛樺璞℃槸鍚﹀瓨鍦�
-     *
-     * @param key 缂撳瓨鐨勯敭鍊�
-     */
-    public static boolean isExistsObject(final String key) {
-        return CLIENT.getBucket(key).isExists();
-    }
-
-    /**
-     * 缂撳瓨List鏁版嵁
-     *
-     * @param key      缂撳瓨鐨勯敭鍊�
-     * @param dataList 寰呯紦瀛樼殑List鏁版嵁
-     * @return 缂撳瓨鐨勫璞�
-     */
-    public static <T> boolean setCacheList(final String key, final List<T> dataList) {
-        RList<T> rList = CLIENT.getList(key);
-        return rList.addAll(dataList);
-    }
-
-    /**
-     * 娉ㄥ唽List鐩戝惉鍣�
-     * <p>
-     * key 鐩戝惉鍣ㄩ渶寮�鍚� `notify-keyspace-events` 绛� redis 鐩稿叧閰嶇疆
-     *
-     * @param key      缂撳瓨鐨勯敭鍊�
-     * @param listener 鐩戝惉鍣ㄩ厤缃�
-     */
-    public static <T> void addListListener(final String key, final ObjectListener listener) {
-        RList<T> rList = CLIENT.getList(key);
-        rList.addListener(listener);
-    }
-
-    /**
-     * 鑾峰緱缂撳瓨鐨刲ist瀵硅薄
-     *
-     * @param key 缂撳瓨鐨勯敭鍊�
-     * @return 缂撳瓨閿�煎搴旂殑鏁版嵁
-     */
-    public static <T> List<T> getCacheList(final String key) {
-        RList<T> rList = CLIENT.getList(key);
-        return rList.readAll();
-    }
-
-    /**
-     * 缂撳瓨Set
-     *
-     * @param key     缂撳瓨閿��
-     * @param dataSet 缂撳瓨鐨勬暟鎹�
-     * @return 缂撳瓨鏁版嵁鐨勫璞�
-     */
-    public static <T> boolean setCacheSet(final String key, final Set<T> dataSet) {
-        RSet<T> rSet = CLIENT.getSet(key);
-        return rSet.addAll(dataSet);
-    }
-
-    /**
-     * 娉ㄥ唽Set鐩戝惉鍣�
-     * <p>
-     * key 鐩戝惉鍣ㄩ渶寮�鍚� `notify-keyspace-events` 绛� redis 鐩稿叧閰嶇疆
-     *
-     * @param key      缂撳瓨鐨勯敭鍊�
-     * @param listener 鐩戝惉鍣ㄩ厤缃�
-     */
-    public static <T> void addSetListener(final String key, final ObjectListener listener) {
-        RSet<T> rSet = CLIENT.getSet(key);
-        rSet.addListener(listener);
-    }
-
-    /**
-     * 鑾峰緱缂撳瓨鐨剆et
-     *
-     * @param key 缂撳瓨鐨刱ey
-     * @return set瀵硅薄
-     */
-    public static <T> Set<T> getCacheSet(final String key) {
-        RSet<T> rSet = CLIENT.getSet(key);
-        return rSet.readAll();
-    }
-
-    /**
-     * 缂撳瓨Map
-     *
-     * @param key     缂撳瓨鐨勯敭鍊�
-     * @param dataMap 缂撳瓨鐨勬暟鎹�
-     */
-    public static <T> void setCacheMap(final String key, final Map<String, T> dataMap) {
-        if (dataMap != null) {
-            RMap<String, T> rMap = CLIENT.getMap(key);
-            rMap.putAll(dataMap);
-        }
-    }
-
-    /**
-     * 娉ㄥ唽Map鐩戝惉鍣�
-     * <p>
-     * key 鐩戝惉鍣ㄩ渶寮�鍚� `notify-keyspace-events` 绛� redis 鐩稿叧閰嶇疆
-     *
-     * @param key      缂撳瓨鐨勯敭鍊�
-     * @param listener 鐩戝惉鍣ㄩ厤缃�
-     */
-    public static <T> void addMapListener(final String key, final ObjectListener listener) {
-        RMap<String, T> rMap = CLIENT.getMap(key);
-        rMap.addListener(listener);
-    }
-
-    /**
-     * 鑾峰緱缂撳瓨鐨凪ap
-     *
-     * @param key 缂撳瓨鐨勯敭鍊�
-     * @return map瀵硅薄
-     */
-    public static <T> Map<String, T> getCacheMap(final String key) {
-        RMap<String, T> rMap = CLIENT.getMap(key);
-        return rMap.getAll(rMap.keySet());
-    }
-
-    /**
-     * 鑾峰緱缂撳瓨Map鐨刱ey鍒楄〃
-     *
-     * @param key 缂撳瓨鐨勯敭鍊�
-     * @return key鍒楄〃
-     */
-    public static <T> Set<String> getCacheMapKeySet(final String key) {
-        RMap<String, T> rMap = CLIENT.getMap(key);
-        return rMap.keySet();
-    }
-
-    /**
-     * 寰�Hash涓瓨鍏ユ暟鎹�
-     *
-     * @param key   Redis閿�
-     * @param hKey  Hash閿�
-     * @param value 鍊�
-     */
-    public static <T> void setCacheMapValue(final String key, final String hKey, final T value) {
-        RMap<String, T> rMap = CLIENT.getMap(key);
-        rMap.put(hKey, value);
-    }
-
-    /**
-     * 鑾峰彇Hash涓殑鏁版嵁
-     *
-     * @param key  Redis閿�
-     * @param hKey Hash閿�
-     * @return Hash涓殑瀵硅薄
-     */
-    public static <T> T getCacheMapValue(final String key, final String hKey) {
-        RMap<String, T> rMap = CLIENT.getMap(key);
-        return rMap.get(hKey);
-    }
-
-    /**
-     * 鍒犻櫎Hash涓殑鏁版嵁
-     *
-     * @param key  Redis閿�
-     * @param hKey Hash閿�
-     * @return Hash涓殑瀵硅薄
-     */
-    public static <T> T delCacheMapValue(final String key, final String hKey) {
-        RMap<String, T> rMap = CLIENT.getMap(key);
-        return rMap.remove(hKey);
-    }
-
-    /**
-     * 鑾峰彇澶氫釜Hash涓殑鏁版嵁
-     *
-     * @param key   Redis閿�
-     * @param hKeys Hash閿泦鍚�
-     * @return Hash瀵硅薄闆嗗悎
-     */
-    public static <K, V> Map<K, V> getMultiCacheMapValue(final String key, final Set<K> hKeys) {
-        RMap<K, V> rMap = CLIENT.getMap(key);
-        return rMap.getAll(hKeys);
-    }
-
-    /**
-     * 璁剧疆鍘熷瓙鍊�
-     *
-     * @param key   Redis閿�
-     * @param value 鍊�
-     */
-    public static void setAtomicValue(String key, long value) {
-        RAtomicLong atomic = CLIENT.getAtomicLong(key);
-        atomic.set(value);
-    }
-
-    /**
-     * 鑾峰彇鍘熷瓙鍊�
-     *
-     * @param key Redis閿�
-     * @return 褰撳墠鍊�
-     */
-    public static long getAtomicValue(String key) {
-        RAtomicLong atomic = CLIENT.getAtomicLong(key);
-        return atomic.get();
-    }
-
-    /**
-     * 閫掑鍘熷瓙鍊�
-     *
-     * @param key Redis閿�
-     * @return 褰撳墠鍊�
-     */
-    public static long incrAtomicValue(String key) {
-        RAtomicLong atomic = CLIENT.getAtomicLong(key);
-        return atomic.incrementAndGet();
-    }
-
-    /**
-     * 閫掑噺鍘熷瓙鍊�
-     *
-     * @param key Redis閿�
-     * @return 褰撳墠鍊�
-     */
-    public static long decrAtomicValue(String key) {
-        RAtomicLong atomic = CLIENT.getAtomicLong(key);
-        return atomic.decrementAndGet();
-    }
-
-    /**
-     * 鑾峰緱缂撳瓨鐨勫熀鏈璞″垪琛�
-     *
-     * @param pattern 瀛楃涓插墠缂�
-     * @return 瀵硅薄鍒楄〃
-     */
-    public static Collection<String> keys(final String pattern) {
-        Stream<String> stream = CLIENT.getKeys().getKeysStreamByPattern(pattern);
-        return stream.collect(Collectors.toList());
-    }
-
-    /**
-     * 鍒犻櫎缂撳瓨鐨勫熀鏈璞″垪琛�
-     *
-     * @param pattern 瀛楃涓插墠缂�
-     */
-    public static void deleteKeys(final String pattern) {
-        CLIENT.getKeys().deleteByPattern(pattern);
-    }
-
-    /**
-     * 妫�鏌edis涓槸鍚﹀瓨鍦╧ey
-     *
-     * @param key 閿�
-     */
-    public static Boolean hasKey(String key) {
-        RKeys rKeys = CLIENT.getKeys();
-        return rKeys.countExists(key) > 0;
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfig.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfig.java
new file mode 100644
index 0000000..644edbe
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfig.java
@@ -0,0 +1,130 @@
+package org.dromara.common.redis.config;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.dromara.common.redis.config.properties.RedissonProperties;
+import org.dromara.common.redis.handler.KeyPrefixHandler;
+import org.dromara.common.redis.manager.PlusSpringCacheManager;
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.codec.JsonJacksonCodec;
+import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * redis閰嶇疆
+ *
+ * @author Lion Li
+ */
+@Slf4j
+@AutoConfiguration
+@EnableCaching
+@EnableConfigurationProperties(RedissonProperties.class)
+public class RedisConfig {
+
+    @Autowired
+    private RedissonProperties redissonProperties;
+
+    @Autowired
+    private ObjectMapper objectMapper;
+
+    @Bean
+    public RedissonAutoConfigurationCustomizer redissonCustomizer() {
+        return config -> {
+            config.setThreads(redissonProperties.getThreads())
+                .setNettyThreads(redissonProperties.getNettyThreads())
+                .setCodec(new JsonJacksonCodec(objectMapper));
+            RedissonProperties.SingleServerConfig singleServerConfig = redissonProperties.getSingleServerConfig();
+            if (ObjectUtil.isNotNull(singleServerConfig)) {
+                // 浣跨敤鍗曟満妯″紡
+                config.useSingleServer()
+                    //璁剧疆redis key鍓嶇紑
+                    .setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix()))
+                    .setTimeout(singleServerConfig.getTimeout())
+                    .setClientName(singleServerConfig.getClientName())
+                    .setIdleConnectionTimeout(singleServerConfig.getIdleConnectionTimeout())
+                    .setSubscriptionConnectionPoolSize(singleServerConfig.getSubscriptionConnectionPoolSize())
+                    .setConnectionMinimumIdleSize(singleServerConfig.getConnectionMinimumIdleSize())
+                    .setConnectionPoolSize(singleServerConfig.getConnectionPoolSize());
+            }
+            // 闆嗙兢閰嶇疆鏂瑰紡 鍙傝�冧笅鏂规敞閲�
+            RedissonProperties.ClusterServersConfig clusterServersConfig = redissonProperties.getClusterServersConfig();
+            if (ObjectUtil.isNotNull(clusterServersConfig)) {
+                config.useClusterServers()
+                    //璁剧疆redis key鍓嶇紑
+                    .setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix()))
+                    .setTimeout(clusterServersConfig.getTimeout())
+                    .setClientName(clusterServersConfig.getClientName())
+                    .setIdleConnectionTimeout(clusterServersConfig.getIdleConnectionTimeout())
+                    .setSubscriptionConnectionPoolSize(clusterServersConfig.getSubscriptionConnectionPoolSize())
+                    .setMasterConnectionMinimumIdleSize(clusterServersConfig.getMasterConnectionMinimumIdleSize())
+                    .setMasterConnectionPoolSize(clusterServersConfig.getMasterConnectionPoolSize())
+                    .setSlaveConnectionMinimumIdleSize(clusterServersConfig.getSlaveConnectionMinimumIdleSize())
+                    .setSlaveConnectionPoolSize(clusterServersConfig.getSlaveConnectionPoolSize())
+                    .setReadMode(clusterServersConfig.getReadMode())
+                    .setSubscriptionMode(clusterServersConfig.getSubscriptionMode());
+            }
+            log.info("鍒濆鍖� redis 閰嶇疆");
+        };
+    }
+
+    /**
+     * 鑷畾涔夌紦瀛樼鐞嗗櫒 鏁村悎spring-cache
+     */
+    @Bean
+    public CacheManager cacheManager() {
+        return new PlusSpringCacheManager();
+    }
+
+    /**
+     * redis闆嗙兢閰嶇疆 yml
+     *
+     * --- # redis 闆嗙兢閰嶇疆(鍗曟満涓庨泦缇ゅ彧鑳藉紑鍚竴涓彟涓�涓渶瑕佹敞閲婃帀)
+     * spring:
+     *   redis:
+     *     cluster:
+     *       nodes:
+     *         - 192.168.0.100:6379
+     *         - 192.168.0.101:6379
+     *         - 192.168.0.102:6379
+     *     # 瀵嗙爜
+     *     password:
+     *     # 杩炴帴瓒呮椂鏃堕棿
+     *     timeout: 10s
+     *     # 鏄惁寮�鍚痵sl
+     *     ssl: false
+     *
+     * redisson:
+     *   # 绾跨▼姹犳暟閲�
+     *   threads: 16
+     *   # Netty绾跨▼姹犳暟閲�
+     *   nettyThreads: 32
+     *   # 闆嗙兢閰嶇疆
+     *   clusterServersConfig:
+     *     # 瀹㈡埛绔悕绉�
+     *     clientName: ${ruoyi.name}
+     *     # master鏈�灏忕┖闂茶繛鎺ユ暟
+     *     masterConnectionMinimumIdleSize: 32
+     *     # master杩炴帴姹犲ぇ灏�
+     *     masterConnectionPoolSize: 64
+     *     # slave鏈�灏忕┖闂茶繛鎺ユ暟
+     *     slaveConnectionMinimumIdleSize: 32
+     *     # slave杩炴帴姹犲ぇ灏�
+     *     slaveConnectionPoolSize: 64
+     *     # 杩炴帴绌洪棽瓒呮椂锛屽崟浣嶏細姣
+     *     idleConnectionTimeout: 10000
+     *     # 鍛戒护绛夊緟瓒呮椂锛屽崟浣嶏細姣
+     *     timeout: 3000
+     *     # 鍙戝竷鍜岃闃呰繛鎺ユ睜澶у皬
+     *     subscriptionConnectionPoolSize: 50
+     *     # 璇诲彇妯″紡
+     *     readMode: "SLAVE"
+     *     # 璁㈤槄妯″紡
+     *     subscriptionMode: "MASTER"
+     */
+
+}
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/properties/RedissonProperties.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/properties/RedissonProperties.java
new file mode 100644
index 0000000..ebec786
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/properties/RedissonProperties.java
@@ -0,0 +1,135 @@
+package org.dromara.common.redis.config.properties;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.redisson.config.ReadMode;
+import org.redisson.config.SubscriptionMode;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * Redisson 閰嶇疆灞炴��
+ *
+ * @author Lion Li
+ */
+@Data
+@ConfigurationProperties(prefix = "redisson")
+public class RedissonProperties {
+
+    /**
+     * redis缂撳瓨key鍓嶇紑
+     */
+    private String keyPrefix;
+
+    /**
+     * 绾跨▼姹犳暟閲�,榛樿鍊� = 褰撳墠澶勭悊鏍告暟閲� * 2
+     */
+    private int threads;
+
+    /**
+     * Netty绾跨▼姹犳暟閲�,榛樿鍊� = 褰撳墠澶勭悊鏍告暟閲� * 2
+     */
+    private int nettyThreads;
+
+    /**
+     * 鍗曟満鏈嶅姟閰嶇疆
+     */
+    private SingleServerConfig singleServerConfig;
+
+    /**
+     * 闆嗙兢鏈嶅姟閰嶇疆
+     */
+    private ClusterServersConfig clusterServersConfig;
+
+    @Data
+    @NoArgsConstructor
+    public static class SingleServerConfig {
+
+        /**
+         * 瀹㈡埛绔悕绉�
+         */
+        private String clientName;
+
+        /**
+         * 鏈�灏忕┖闂茶繛鎺ユ暟
+         */
+        private int connectionMinimumIdleSize;
+
+        /**
+         * 杩炴帴姹犲ぇ灏�
+         */
+        private int connectionPoolSize;
+
+        /**
+         * 杩炴帴绌洪棽瓒呮椂锛屽崟浣嶏細姣
+         */
+        private int idleConnectionTimeout;
+
+        /**
+         * 鍛戒护绛夊緟瓒呮椂锛屽崟浣嶏細姣
+         */
+        private int timeout;
+
+        /**
+         * 鍙戝竷鍜岃闃呰繛鎺ユ睜澶у皬
+         */
+        private int subscriptionConnectionPoolSize;
+
+    }
+
+    @Data
+    @NoArgsConstructor
+    public static class ClusterServersConfig {
+
+        /**
+         * 瀹㈡埛绔悕绉�
+         */
+        private String clientName;
+
+        /**
+         * master鏈�灏忕┖闂茶繛鎺ユ暟
+         */
+        private int masterConnectionMinimumIdleSize;
+
+        /**
+         * master杩炴帴姹犲ぇ灏�
+         */
+        private int masterConnectionPoolSize;
+
+        /**
+         * slave鏈�灏忕┖闂茶繛鎺ユ暟
+         */
+        private int slaveConnectionMinimumIdleSize;
+
+        /**
+         * slave杩炴帴姹犲ぇ灏�
+         */
+        private int slaveConnectionPoolSize;
+
+        /**
+         * 杩炴帴绌洪棽瓒呮椂锛屽崟浣嶏細姣
+         */
+        private int idleConnectionTimeout;
+
+        /**
+         * 鍛戒护绛夊緟瓒呮椂锛屽崟浣嶏細姣
+         */
+        private int timeout;
+
+        /**
+         * 鍙戝竷鍜岃闃呰繛鎺ユ睜澶у皬
+         */
+        private int subscriptionConnectionPoolSize;
+
+        /**
+         * 璇诲彇妯″紡
+         */
+        private ReadMode readMode;
+
+        /**
+         * 璁㈤槄妯″紡
+         */
+        private SubscriptionMode subscriptionMode;
+
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/handler/KeyPrefixHandler.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/handler/KeyPrefixHandler.java
new file mode 100644
index 0000000..3bf3e34
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/handler/KeyPrefixHandler.java
@@ -0,0 +1,50 @@
+package org.dromara.common.redis.handler;
+
+import org.dromara.common.core.utils.StringUtils;
+import org.redisson.api.NameMapper;
+
+/**
+ * redis缂撳瓨key鍓嶇紑澶勭悊
+ *
+ * @author ye
+ * @date 2022/7/14 17:44
+ * @since 4.3.0
+ */
+public class KeyPrefixHandler implements NameMapper {
+
+    private final String keyPrefix;
+
+    public KeyPrefixHandler(String keyPrefix) {
+        //鍓嶇紑涓虹┖ 鍒欒繑鍥炵┖鍓嶇紑
+        this.keyPrefix = StringUtils.isBlank(keyPrefix) ? "" : keyPrefix + ":";
+    }
+
+    /**
+     * 澧炲姞鍓嶇紑
+     */
+    @Override
+    public String map(String name) {
+        if (StringUtils.isBlank(name)) {
+            return null;
+        }
+        if (StringUtils.isNotBlank(keyPrefix) && !name.startsWith(keyPrefix)) {
+            return keyPrefix + name;
+        }
+        return name;
+    }
+
+    /**
+     * 鍘婚櫎鍓嶇紑
+     */
+    @Override
+    public String unmap(String name) {
+        if (StringUtils.isBlank(name)) {
+            return null;
+        }
+        if (StringUtils.isNotBlank(keyPrefix) && name.startsWith(keyPrefix)) {
+            return name.substring(keyPrefix.length());
+        }
+        return name;
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/PlusSpringCacheManager.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/PlusSpringCacheManager.java
new file mode 100644
index 0000000..2a1391d
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/PlusSpringCacheManager.java
@@ -0,0 +1,191 @@
+/**
+ * Copyright (c) 2013-2021 Nikita Koksharov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.dromara.common.redis.manager;
+
+import org.dromara.common.redis.utils.RedisUtils;
+import org.redisson.api.RMap;
+import org.redisson.api.RMapCache;
+import org.redisson.spring.cache.CacheConfig;
+import org.redisson.spring.cache.RedissonCache;
+import org.springframework.boot.convert.DurationStyle;
+import org.springframework.cache.Cache;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.transaction.TransactionAwareCacheDecorator;
+import org.springframework.util.StringUtils;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * A {@link org.springframework.cache.CacheManager} implementation
+ * backed by Redisson instance.
+ * <p>
+ * 淇敼 RedissonSpringCacheManager 婧愮爜
+ * 閲嶅啓 cacheName 澶勭悊鏂规硶 鏀寔澶氬弬鏁�
+ *
+ * @author Nikita Koksharov
+ *
+ */
+@SuppressWarnings("unchecked")
+public class PlusSpringCacheManager implements CacheManager {
+
+    private boolean dynamic = true;
+
+    private boolean allowNullValues = true;
+
+    private boolean transactionAware = true;
+
+    Map<String, CacheConfig> configMap = new ConcurrentHashMap<>();
+    ConcurrentMap<String, Cache> instanceMap = new ConcurrentHashMap<>();
+
+    /**
+     * Creates CacheManager supplied by Redisson instance
+     */
+    public PlusSpringCacheManager() {
+    }
+
+
+    /**
+     * Defines possibility of storing {@code null} values.
+     * <p>
+     * Default is <code>true</code>
+     *
+     * @param allowNullValues stores if <code>true</code>
+     */
+    public void setAllowNullValues(boolean allowNullValues) {
+        this.allowNullValues = allowNullValues;
+    }
+
+    /**
+     * Defines if cache aware of Spring-managed transactions.
+     * If {@code true} put/evict operations are executed only for successful transaction in after-commit phase.
+     * <p>
+     * Default is <code>false</code>
+     *
+     * @param transactionAware cache is transaction aware if <code>true</code>
+     */
+    public void setTransactionAware(boolean transactionAware) {
+        this.transactionAware = transactionAware;
+    }
+
+    /**
+     * Defines 'fixed' cache names.
+     * A new cache instance will not be created in dynamic for non-defined names.
+     * <p>
+     * `null` parameter setups dynamic mode
+     *
+     * @param names of caches
+     */
+    public void setCacheNames(Collection<String> names) {
+        if (names != null) {
+            for (String name : names) {
+                getCache(name);
+            }
+            dynamic = false;
+        } else {
+            dynamic = true;
+        }
+    }
+
+    /**
+     * Set cache config mapped by cache name
+     *
+     * @param config object
+     */
+    public void setConfig(Map<String, ? extends CacheConfig> config) {
+        this.configMap = (Map<String, CacheConfig>) config;
+    }
+
+    protected CacheConfig createDefaultConfig() {
+        return new CacheConfig();
+    }
+
+    @Override
+    public Cache getCache(String name) {
+        Cache cache = instanceMap.get(name);
+        if (cache != null) {
+            return cache;
+        }
+        if (!dynamic) {
+            return cache;
+        }
+
+        CacheConfig config = configMap.get(name);
+        if (config == null) {
+            config = createDefaultConfig();
+            configMap.put(name, config);
+        }
+
+        // 閲嶅啓 cacheName 鏀寔澶氬弬鏁�
+        String[] array = StringUtils.delimitedListToStringArray(name, "#");
+        name = array[0];
+        if (array.length > 1) {
+            config.setTTL(DurationStyle.detectAndParse(array[1]).toMillis());
+        }
+        if (array.length > 2) {
+            config.setMaxIdleTime(DurationStyle.detectAndParse(array[2]).toMillis());
+        }
+        if (array.length > 3) {
+            config.setMaxSize(Integer.parseInt(array[3]));
+        }
+
+        if (config.getMaxIdleTime() == 0 && config.getTTL() == 0 && config.getMaxSize() == 0) {
+            return createMap(name, config);
+        }
+
+        return createMapCache(name, config);
+    }
+
+    private Cache createMap(String name, CacheConfig config) {
+        RMap<Object, Object> map = RedisUtils.getClient().getMap(name);
+
+        Cache cache = new RedissonCache(map, allowNullValues);
+        if (transactionAware) {
+            cache = new TransactionAwareCacheDecorator(cache);
+        }
+        Cache oldCache = instanceMap.putIfAbsent(name, cache);
+        if (oldCache != null) {
+            cache = oldCache;
+        }
+        return cache;
+    }
+
+    private Cache createMapCache(String name, CacheConfig config) {
+        RMapCache<Object, Object> map = RedisUtils.getClient().getMapCache(name);
+
+        Cache cache = new RedissonCache(map, config, allowNullValues);
+        if (transactionAware) {
+            cache = new TransactionAwareCacheDecorator(cache);
+        }
+        Cache oldCache = instanceMap.putIfAbsent(name, cache);
+        if (oldCache != null) {
+            cache = oldCache;
+        } else {
+            map.setMaxSize(config.getMaxSize());
+        }
+        return cache;
+    }
+
+    @Override
+    public Collection<String> getCacheNames() {
+        return Collections.unmodifiableSet(configMap.keySet());
+    }
+
+
+}
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/CacheUtils.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/CacheUtils.java
new file mode 100644
index 0000000..42a88d6
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/CacheUtils.java
@@ -0,0 +1,75 @@
+package org.dromara.common.redis.utils;
+
+import org.dromara.common.core.utils.SpringUtils;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.redisson.api.RMap;
+import org.springframework.cache.Cache;
+import org.springframework.cache.CacheManager;
+
+import java.util.Set;
+
+/**
+ * 缂撳瓨鎿嶄綔宸ュ叿绫� {@link }
+ *
+ * @author Michelle.Chung
+ * @date 2022/8/13
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+@SuppressWarnings(value = {"unchecked"})
+public class CacheUtils {
+
+    private static final CacheManager CACHE_MANAGER = SpringUtils.getBean(CacheManager.class);
+
+    /**
+     * 鑾峰彇缂撳瓨缁勫唴鎵�鏈夌殑KEY
+     *
+     * @param cacheNames 缂撳瓨缁勫悕绉�
+     */
+    public static Set<Object> keys(String cacheNames) {
+        RMap<Object, Object> rmap = (RMap<Object, Object>) CACHE_MANAGER.getCache(cacheNames).getNativeCache();
+        return rmap.keySet();
+    }
+
+    /**
+     * 鑾峰彇缂撳瓨鍊�
+     *
+     * @param cacheNames 缂撳瓨缁勫悕绉�
+     * @param key        缂撳瓨key
+     */
+    public static <T> T get(String cacheNames, Object key) {
+        Cache.ValueWrapper wrapper = CACHE_MANAGER.getCache(cacheNames).get(key);
+        return wrapper != null ? (T) wrapper.get() : null;
+    }
+
+    /**
+     * 淇濆瓨缂撳瓨鍊�
+     *
+     * @param cacheNames 缂撳瓨缁勫悕绉�
+     * @param key        缂撳瓨key
+     * @param value      缂撳瓨鍊�
+     */
+    public static void put(String cacheNames, Object key, Object value) {
+        CACHE_MANAGER.getCache(cacheNames).put(key, value);
+    }
+
+    /**
+     * 鍒犻櫎缂撳瓨鍊�
+     *
+     * @param cacheNames 缂撳瓨缁勫悕绉�
+     * @param key        缂撳瓨key
+     */
+    public static void evict(String cacheNames, Object key) {
+        CACHE_MANAGER.getCache(cacheNames).evict(key);
+    }
+
+    /**
+     * 娓呯┖缂撳瓨鍊�
+     *
+     * @param cacheNames 缂撳瓨缁勫悕绉�
+     */
+    public static void clear(String cacheNames) {
+        CACHE_MANAGER.getCache(cacheNames).clear();
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/QueueUtils.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/QueueUtils.java
new file mode 100644
index 0000000..45b5496
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/QueueUtils.java
@@ -0,0 +1,180 @@
+package org.dromara.common.redis.utils;
+
+import org.dromara.common.core.utils.SpringUtils;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.redisson.api.*;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+
+/**
+ * 鍒嗗竷寮忛槦鍒楀伐鍏�
+ * 杞婚噺绾ч槦鍒� 閲嶉噺绾ф暟鎹噺 璇蜂娇鐢� MQ
+ * 瑕佹眰 redis 5.X 浠ヤ笂
+ *
+ * @author Lion Li
+ * @version 3.6.0 鏂板
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class QueueUtils {
+
+    private static final RedissonClient CLIENT = SpringUtils.getBean(RedissonClient.class);
+
+
+    /**
+     * 鑾峰彇瀹㈡埛绔疄渚�
+     */
+    public static RedissonClient getClient() {
+        return CLIENT;
+    }
+
+    /**
+     * 娣诲姞鏅�氶槦鍒楁暟鎹�
+     *
+     * @param queueName 闃熷垪鍚�
+     * @param data      鏁版嵁
+     */
+    public static <T> boolean addQueueObject(String queueName, T data) {
+        RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
+        return queue.offer(data);
+    }
+
+    /**
+     * 閫氱敤鑾峰彇涓�涓槦鍒楁暟鎹� 娌℃湁鏁版嵁杩斿洖 null(涓嶆敮鎸佸欢杩熼槦鍒�)
+     *
+     * @param queueName 闃熷垪鍚�
+     */
+    public static <T> T getQueueObject(String queueName) {
+        RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
+        return queue.poll();
+    }
+
+    /**
+     * 閫氱敤鍒犻櫎闃熷垪鏁版嵁(涓嶆敮鎸佸欢杩熼槦鍒�)
+     */
+    public static <T> boolean removeQueueObject(String queueName, T data) {
+        RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
+        return queue.remove(data);
+    }
+
+    /**
+     * 閫氱敤閿�姣侀槦鍒� 鎵�鏈夐樆濉炵洃鍚� 鎶ラ敊(涓嶆敮鎸佸欢杩熼槦鍒�)
+     */
+    public static <T> boolean destroyQueue(String queueName) {
+        RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
+        return queue.delete();
+    }
+
+    /**
+     * 娣诲姞寤惰繜闃熷垪鏁版嵁 榛樿姣
+     *
+     * @param queueName 闃熷垪鍚�
+     * @param data      鏁版嵁
+     * @param time      寤惰繜鏃堕棿
+     */
+    public static <T> void addDelayedQueueObject(String queueName, T data, long time) {
+        addDelayedQueueObject(queueName, data, time, TimeUnit.MILLISECONDS);
+    }
+
+    /**
+     * 娣诲姞寤惰繜闃熷垪鏁版嵁
+     *
+     * @param queueName 闃熷垪鍚�
+     * @param data      鏁版嵁
+     * @param time      寤惰繜鏃堕棿
+     * @param timeUnit  鍗曚綅
+     */
+    public static <T> void addDelayedQueueObject(String queueName, T data, long time, TimeUnit timeUnit) {
+        RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
+        RDelayedQueue<T> delayedQueue = CLIENT.getDelayedQueue(queue);
+        delayedQueue.offer(data, time, timeUnit);
+    }
+
+    /**
+     * 鑾峰彇涓�涓欢杩熼槦鍒楁暟鎹� 娌℃湁鏁版嵁杩斿洖 null
+     *
+     * @param queueName 闃熷垪鍚�
+     */
+    public static <T> T getDelayedQueueObject(String queueName) {
+        RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
+        RDelayedQueue<T> delayedQueue = CLIENT.getDelayedQueue(queue);
+        return delayedQueue.poll();
+    }
+
+    /**
+     * 鍒犻櫎寤惰繜闃熷垪鏁版嵁
+     */
+    public static <T> boolean removeDelayedQueueObject(String queueName, T data) {
+        RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
+        RDelayedQueue<T> delayedQueue = CLIENT.getDelayedQueue(queue);
+        return delayedQueue.remove(data);
+    }
+
+    /**
+     * 閿�姣佸欢杩熼槦鍒� 鎵�鏈夐樆濉炵洃鍚� 鎶ラ敊
+     */
+    public static <T> void destroyDelayedQueue(String queueName) {
+        RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
+        RDelayedQueue<T> delayedQueue = CLIENT.getDelayedQueue(queue);
+        delayedQueue.destroy();
+    }
+
+    /**
+     * 娣诲姞浼樺厛闃熷垪鏁版嵁
+     *
+     * @param queueName 闃熷垪鍚�
+     * @param data      鏁版嵁
+     */
+    public static <T> boolean addPriorityQueueObject(String queueName, T data) {
+        RPriorityBlockingQueue<T> priorityBlockingQueue = CLIENT.getPriorityBlockingQueue(queueName);
+        return priorityBlockingQueue.offer(data);
+    }
+
+    /**
+     * 灏濊瘯璁剧疆 鏈夌晫闃熷垪 瀹归噺 鐢ㄤ簬闄愬埗鏁伴噺
+     *
+     * @param queueName 闃熷垪鍚�
+     * @param capacity  瀹归噺
+     */
+    public static <T> boolean trySetBoundedQueueCapacity(String queueName, int capacity) {
+        RBoundedBlockingQueue<T> boundedBlockingQueue = CLIENT.getBoundedBlockingQueue(queueName);
+        return boundedBlockingQueue.trySetCapacity(capacity);
+    }
+
+    /**
+     * 灏濊瘯璁剧疆 鏈夌晫闃熷垪 瀹归噺 鐢ㄤ簬闄愬埗鏁伴噺
+     *
+     * @param queueName 闃熷垪鍚�
+     * @param capacity  瀹归噺
+     * @param destroy   宸插瓨鍦ㄦ槸鍚﹂攢姣�
+     */
+    public static <T> boolean trySetBoundedQueueCapacity(String queueName, int capacity, boolean destroy) {
+        RBoundedBlockingQueue<T> boundedBlockingQueue = CLIENT.getBoundedBlockingQueue(queueName);
+        if (boundedBlockingQueue.isExists() && destroy) {
+            destroyQueue(queueName);
+        }
+        return boundedBlockingQueue.trySetCapacity(capacity);
+    }
+
+    /**
+     * 娣诲姞鏈夌晫闃熷垪鏁版嵁
+     *
+     * @param queueName 闃熷垪鍚�
+     * @param data      鏁版嵁
+     * @return 娣诲姞鎴愬姛 true 宸茶揪鍒扮晫闄� false
+     */
+    public static <T> boolean addBoundedQueueObject(String queueName, T data) {
+        RBoundedBlockingQueue<T> boundedBlockingQueue = CLIENT.getBoundedBlockingQueue(queueName);
+        return boundedBlockingQueue.offer(data);
+    }
+
+    /**
+     * 璁㈤槄闃诲闃熷垪(鍙闃呮墍鏈夊疄鐜扮被 渚嬪: 寤惰繜 浼樺厛 鏈夌晫 绛�)
+     */
+    public static <T> void subscribeBlockingQueue(String queueName, Consumer<T> consumer) {
+        RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
+        queue.subscribeOnElements(consumer);
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/RedisUtils.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/RedisUtils.java
new file mode 100644
index 0000000..fd20ba0
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/RedisUtils.java
@@ -0,0 +1,462 @@
+package org.dromara.common.redis.utils;
+
+import org.dromara.common.core.utils.SpringUtils;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.redisson.api.*;
+
+import java.time.Duration;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * redis 宸ュ叿绫�
+ *
+ * @author Lion Li
+ * @version 3.1.0 鏂板
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+@SuppressWarnings(value = {"unchecked", "rawtypes"})
+public class RedisUtils {
+
+    private static final RedissonClient CLIENT = SpringUtils.getBean(RedissonClient.class);
+
+    /**
+     * 闄愭祦
+     *
+     * @param key          闄愭祦key
+     * @param rateType     闄愭祦绫诲瀷
+     * @param rate         閫熺巼
+     * @param rateInterval 閫熺巼闂撮殧
+     * @return -1 琛ㄧず澶辫触
+     */
+    public static long rateLimiter(String key, RateType rateType, int rate, int rateInterval) {
+        RRateLimiter rateLimiter = CLIENT.getRateLimiter(key);
+        rateLimiter.trySetRate(rateType, rate, rateInterval, RateIntervalUnit.SECONDS);
+        if (rateLimiter.tryAcquire()) {
+            return rateLimiter.availablePermits();
+        } else {
+            return -1L;
+        }
+    }
+
+    /**
+     * 鑾峰彇瀹㈡埛绔疄渚�
+     */
+    public static RedissonClient getClient() {
+        return CLIENT;
+    }
+
+    /**
+     * 鍙戝竷閫氶亾娑堟伅
+     *
+     * @param channelKey 閫氶亾key
+     * @param msg        鍙戦�佹暟鎹�
+     * @param consumer   鑷畾涔夊鐞�
+     */
+    public static <T> void publish(String channelKey, T msg, Consumer<T> consumer) {
+        RTopic topic = CLIENT.getTopic(channelKey);
+        topic.publish(msg);
+        consumer.accept(msg);
+    }
+
+    public static <T> void publish(String channelKey, T msg) {
+        RTopic topic = CLIENT.getTopic(channelKey);
+        topic.publish(msg);
+    }
+
+    /**
+     * 璁㈤槄閫氶亾鎺ユ敹娑堟伅
+     *
+     * @param channelKey 閫氶亾key
+     * @param clazz      娑堟伅绫诲瀷
+     * @param consumer   鑷畾涔夊鐞�
+     */
+    public static <T> void subscribe(String channelKey, Class<T> clazz, Consumer<T> consumer) {
+        RTopic topic = CLIENT.getTopic(channelKey);
+        topic.addListener(clazz, (channel, msg) -> consumer.accept(msg));
+    }
+
+    /**
+     * 缂撳瓨鍩烘湰鐨勫璞★紝Integer銆丼tring銆佸疄浣撶被绛�
+     *
+     * @param key   缂撳瓨鐨勯敭鍊�
+     * @param value 缂撳瓨鐨勫��
+     */
+    public static <T> void setCacheObject(final String key, final T 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<T> bucket = CLIENT.getBucket(key);
+        if (isSaveTtl) {
+            try {
+                bucket.setAndKeepTTL(value);
+            } catch (Exception e) {
+                long timeToLive = bucket.remainTimeToLive();
+                setCacheObject(key, value, Duration.ofMillis(timeToLive));
+            }
+        } else {
+            bucket.set(value);
+        }
+    }
+
+    /**
+     * 缂撳瓨鍩烘湰鐨勫璞★紝Integer銆丼tring銆佸疄浣撶被绛�
+     *
+     * @param key      缂撳瓨鐨勯敭鍊�
+     * @param value    缂撳瓨鐨勫��
+     * @param duration 鏃堕棿
+     */
+    public static <T> void setCacheObject(final String key, final T value, final Duration duration) {
+        RBatch batch = CLIENT.createBatch();
+        RBucketAsync<T> bucket = batch.getBucket(key);
+        bucket.setAsync(value);
+        bucket.expireAsync(duration);
+        batch.execute();
+    }
+
+    /**
+     * 娉ㄥ唽瀵硅薄鐩戝惉鍣�
+     * <p>
+     * key 鐩戝惉鍣ㄩ渶寮�鍚� `notify-keyspace-events` 绛� redis 鐩稿叧閰嶇疆
+     *
+     * @param key      缂撳瓨鐨勯敭鍊�
+     * @param listener 鐩戝惉鍣ㄩ厤缃�
+     */
+    public static <T> void addObjectListener(final String key, final ObjectListener listener) {
+        RBucket<T> result = CLIENT.getBucket(key);
+        result.addListener(listener);
+    }
+
+    /**
+     * 璁剧疆鏈夋晥鏃堕棿
+     *
+     * @param key     Redis閿�
+     * @param timeout 瓒呮椂鏃堕棿
+     * @return true=璁剧疆鎴愬姛锛沠alse=璁剧疆澶辫触
+     */
+    public static boolean expire(final String key, final long timeout) {
+        return expire(key, Duration.ofSeconds(timeout));
+    }
+
+    /**
+     * 璁剧疆鏈夋晥鏃堕棿
+     *
+     * @param key      Redis閿�
+     * @param duration 瓒呮椂鏃堕棿
+     * @return true=璁剧疆鎴愬姛锛沠alse=璁剧疆澶辫触
+     */
+    public static boolean expire(final String key, final Duration duration) {
+        RBucket rBucket = CLIENT.getBucket(key);
+        return rBucket.expire(duration);
+    }
+
+    /**
+     * 鑾峰緱缂撳瓨鐨勫熀鏈璞°��
+     *
+     * @param key 缂撳瓨閿��
+     * @return 缂撳瓨閿�煎搴旂殑鏁版嵁
+     */
+    public static <T> T getCacheObject(final String key) {
+        RBucket<T> rBucket = CLIENT.getBucket(key);
+        return rBucket.get();
+    }
+
+    /**
+     * 鑾峰緱key鍓╀綑瀛樻椿鏃堕棿
+     *
+     * @param key 缂撳瓨閿��
+     * @return 鍓╀綑瀛樻椿鏃堕棿
+     */
+    public static <T> long getTimeToLive(final String key) {
+        RBucket<T> rBucket = CLIENT.getBucket(key);
+        return rBucket.remainTimeToLive();
+    }
+
+    /**
+     * 鍒犻櫎鍗曚釜瀵硅薄
+     *
+     * @param key 缂撳瓨鐨勯敭鍊�
+     */
+    public static boolean deleteObject(final String key) {
+        return CLIENT.getBucket(key).delete();
+    }
+
+    /**
+     * 鍒犻櫎闆嗗悎瀵硅薄
+     *
+     * @param collection 澶氫釜瀵硅薄
+     */
+    public static void deleteObject(final Collection collection) {
+        RBatch batch = CLIENT.createBatch();
+        collection.forEach(t -> {
+            batch.getBucket(t.toString()).deleteAsync();
+        });
+        batch.execute();
+    }
+
+    /**
+     * 妫�鏌ョ紦瀛樺璞℃槸鍚﹀瓨鍦�
+     *
+     * @param key 缂撳瓨鐨勯敭鍊�
+     */
+    public static boolean isExistsObject(final String key) {
+        return CLIENT.getBucket(key).isExists();
+    }
+
+    /**
+     * 缂撳瓨List鏁版嵁
+     *
+     * @param key      缂撳瓨鐨勯敭鍊�
+     * @param dataList 寰呯紦瀛樼殑List鏁版嵁
+     * @return 缂撳瓨鐨勫璞�
+     */
+    public static <T> boolean setCacheList(final String key, final List<T> dataList) {
+        RList<T> rList = CLIENT.getList(key);
+        return rList.addAll(dataList);
+    }
+
+    /**
+     * 娉ㄥ唽List鐩戝惉鍣�
+     * <p>
+     * key 鐩戝惉鍣ㄩ渶寮�鍚� `notify-keyspace-events` 绛� redis 鐩稿叧閰嶇疆
+     *
+     * @param key      缂撳瓨鐨勯敭鍊�
+     * @param listener 鐩戝惉鍣ㄩ厤缃�
+     */
+    public static <T> void addListListener(final String key, final ObjectListener listener) {
+        RList<T> rList = CLIENT.getList(key);
+        rList.addListener(listener);
+    }
+
+    /**
+     * 鑾峰緱缂撳瓨鐨刲ist瀵硅薄
+     *
+     * @param key 缂撳瓨鐨勯敭鍊�
+     * @return 缂撳瓨閿�煎搴旂殑鏁版嵁
+     */
+    public static <T> List<T> getCacheList(final String key) {
+        RList<T> rList = CLIENT.getList(key);
+        return rList.readAll();
+    }
+
+    /**
+     * 缂撳瓨Set
+     *
+     * @param key     缂撳瓨閿��
+     * @param dataSet 缂撳瓨鐨勬暟鎹�
+     * @return 缂撳瓨鏁版嵁鐨勫璞�
+     */
+    public static <T> boolean setCacheSet(final String key, final Set<T> dataSet) {
+        RSet<T> rSet = CLIENT.getSet(key);
+        return rSet.addAll(dataSet);
+    }
+
+    /**
+     * 娉ㄥ唽Set鐩戝惉鍣�
+     * <p>
+     * key 鐩戝惉鍣ㄩ渶寮�鍚� `notify-keyspace-events` 绛� redis 鐩稿叧閰嶇疆
+     *
+     * @param key      缂撳瓨鐨勯敭鍊�
+     * @param listener 鐩戝惉鍣ㄩ厤缃�
+     */
+    public static <T> void addSetListener(final String key, final ObjectListener listener) {
+        RSet<T> rSet = CLIENT.getSet(key);
+        rSet.addListener(listener);
+    }
+
+    /**
+     * 鑾峰緱缂撳瓨鐨剆et
+     *
+     * @param key 缂撳瓨鐨刱ey
+     * @return set瀵硅薄
+     */
+    public static <T> Set<T> getCacheSet(final String key) {
+        RSet<T> rSet = CLIENT.getSet(key);
+        return rSet.readAll();
+    }
+
+    /**
+     * 缂撳瓨Map
+     *
+     * @param key     缂撳瓨鐨勯敭鍊�
+     * @param dataMap 缂撳瓨鐨勬暟鎹�
+     */
+    public static <T> void setCacheMap(final String key, final Map<String, T> dataMap) {
+        if (dataMap != null) {
+            RMap<String, T> rMap = CLIENT.getMap(key);
+            rMap.putAll(dataMap);
+        }
+    }
+
+    /**
+     * 娉ㄥ唽Map鐩戝惉鍣�
+     * <p>
+     * key 鐩戝惉鍣ㄩ渶寮�鍚� `notify-keyspace-events` 绛� redis 鐩稿叧閰嶇疆
+     *
+     * @param key      缂撳瓨鐨勯敭鍊�
+     * @param listener 鐩戝惉鍣ㄩ厤缃�
+     */
+    public static <T> void addMapListener(final String key, final ObjectListener listener) {
+        RMap<String, T> rMap = CLIENT.getMap(key);
+        rMap.addListener(listener);
+    }
+
+    /**
+     * 鑾峰緱缂撳瓨鐨凪ap
+     *
+     * @param key 缂撳瓨鐨勯敭鍊�
+     * @return map瀵硅薄
+     */
+    public static <T> Map<String, T> getCacheMap(final String key) {
+        RMap<String, T> rMap = CLIENT.getMap(key);
+        return rMap.getAll(rMap.keySet());
+    }
+
+    /**
+     * 鑾峰緱缂撳瓨Map鐨刱ey鍒楄〃
+     *
+     * @param key 缂撳瓨鐨勯敭鍊�
+     * @return key鍒楄〃
+     */
+    public static <T> Set<String> getCacheMapKeySet(final String key) {
+        RMap<String, T> rMap = CLIENT.getMap(key);
+        return rMap.keySet();
+    }
+
+    /**
+     * 寰�Hash涓瓨鍏ユ暟鎹�
+     *
+     * @param key   Redis閿�
+     * @param hKey  Hash閿�
+     * @param value 鍊�
+     */
+    public static <T> void setCacheMapValue(final String key, final String hKey, final T value) {
+        RMap<String, T> rMap = CLIENT.getMap(key);
+        rMap.put(hKey, value);
+    }
+
+    /**
+     * 鑾峰彇Hash涓殑鏁版嵁
+     *
+     * @param key  Redis閿�
+     * @param hKey Hash閿�
+     * @return Hash涓殑瀵硅薄
+     */
+    public static <T> T getCacheMapValue(final String key, final String hKey) {
+        RMap<String, T> rMap = CLIENT.getMap(key);
+        return rMap.get(hKey);
+    }
+
+    /**
+     * 鍒犻櫎Hash涓殑鏁版嵁
+     *
+     * @param key  Redis閿�
+     * @param hKey Hash閿�
+     * @return Hash涓殑瀵硅薄
+     */
+    public static <T> T delCacheMapValue(final String key, final String hKey) {
+        RMap<String, T> rMap = CLIENT.getMap(key);
+        return rMap.remove(hKey);
+    }
+
+    /**
+     * 鑾峰彇澶氫釜Hash涓殑鏁版嵁
+     *
+     * @param key   Redis閿�
+     * @param hKeys Hash閿泦鍚�
+     * @return Hash瀵硅薄闆嗗悎
+     */
+    public static <K, V> Map<K, V> getMultiCacheMapValue(final String key, final Set<K> hKeys) {
+        RMap<K, V> rMap = CLIENT.getMap(key);
+        return rMap.getAll(hKeys);
+    }
+
+    /**
+     * 璁剧疆鍘熷瓙鍊�
+     *
+     * @param key   Redis閿�
+     * @param value 鍊�
+     */
+    public static void setAtomicValue(String key, long value) {
+        RAtomicLong atomic = CLIENT.getAtomicLong(key);
+        atomic.set(value);
+    }
+
+    /**
+     * 鑾峰彇鍘熷瓙鍊�
+     *
+     * @param key Redis閿�
+     * @return 褰撳墠鍊�
+     */
+    public static long getAtomicValue(String key) {
+        RAtomicLong atomic = CLIENT.getAtomicLong(key);
+        return atomic.get();
+    }
+
+    /**
+     * 閫掑鍘熷瓙鍊�
+     *
+     * @param key Redis閿�
+     * @return 褰撳墠鍊�
+     */
+    public static long incrAtomicValue(String key) {
+        RAtomicLong atomic = CLIENT.getAtomicLong(key);
+        return atomic.incrementAndGet();
+    }
+
+    /**
+     * 閫掑噺鍘熷瓙鍊�
+     *
+     * @param key Redis閿�
+     * @return 褰撳墠鍊�
+     */
+    public static long decrAtomicValue(String key) {
+        RAtomicLong atomic = CLIENT.getAtomicLong(key);
+        return atomic.decrementAndGet();
+    }
+
+    /**
+     * 鑾峰緱缂撳瓨鐨勫熀鏈璞″垪琛�
+     *
+     * @param pattern 瀛楃涓插墠缂�
+     * @return 瀵硅薄鍒楄〃
+     */
+    public static Collection<String> keys(final String pattern) {
+        Stream<String> stream = CLIENT.getKeys().getKeysStreamByPattern(pattern);
+        return stream.collect(Collectors.toList());
+    }
+
+    /**
+     * 鍒犻櫎缂撳瓨鐨勫熀鏈璞″垪琛�
+     *
+     * @param pattern 瀛楃涓插墠缂�
+     */
+    public static void deleteKeys(final String pattern) {
+        CLIENT.getKeys().deleteByPattern(pattern);
+    }
+
+    /**
+     * 妫�鏌edis涓槸鍚﹀瓨鍦╧ey
+     *
+     * @param key 閿�
+     */
+    public static Boolean hasKey(String key) {
+        RKeys rKeys = CLIENT.getKeys();
+        return rKeys.countExists(key) > 0;
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index fe5d8b9..59192c5 100644
--- a/ruoyi-common/ruoyi-common-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-common/ruoyi-common-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +1 @@
-com.ruoyi.common.redis.config.RedisConfig
+org.dromara.common.redis.config.RedisConfig
diff --git a/ruoyi-common/ruoyi-common-satoken/pom.xml b/ruoyi-common/ruoyi-common-satoken/pom.xml
index 67fc7e0..6a42b2e 100644
--- a/ruoyi-common/ruoyi-common-satoken/pom.xml
+++ b/ruoyi-common/ruoyi-common-satoken/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-common</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -15,13 +15,13 @@
     <dependencies>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-core</artifactId>
         </dependency>
 
         <!-- RuoYi Common Redis-->
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-redis</artifactId>
         </dependency>
 
diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/com/ruoyi/common/satoken/config/SaTokenConfig.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/com/ruoyi/common/satoken/config/SaTokenConfig.java
deleted file mode 100644
index 609e3ec..0000000
--- a/ruoyi-common/ruoyi-common-satoken/src/main/java/com/ruoyi/common/satoken/config/SaTokenConfig.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.ruoyi.common.satoken.config;
-
-import cn.dev33.satoken.dao.SaTokenDao;
-import cn.dev33.satoken.jwt.StpLogicJwtForSimple;
-import cn.dev33.satoken.stp.StpInterface;
-import cn.dev33.satoken.stp.StpLogic;
-import com.ruoyi.common.satoken.core.dao.PlusSaTokenDao;
-import com.ruoyi.common.satoken.core.service.SaPermissionImpl;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.context.annotation.Bean;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
-/**
- * sa-token 閰嶇疆
- *
- * @author Lion Li
- */
-@AutoConfiguration
-public class SaTokenConfig implements WebMvcConfigurer {
-
-    @Bean
-    public StpLogic getStpLogicJwt() {
-        // Sa-Token 鏁村悎 jwt (绠�鍗曟ā寮�)
-        return new StpLogicJwtForSimple();
-    }
-
-    /**
-     * 鏉冮檺鎺ュ彛瀹炵幇(浣跨敤bean娉ㄥ叆鏂逛究鐢ㄦ埛鏇挎崲)
-     */
-    @Bean
-    public StpInterface stpInterface() {
-        return new SaPermissionImpl();
-    }
-
-    /**
-     * 鑷畾涔塪ao灞傚瓨鍌�
-     */
-    @Bean
-    public SaTokenDao saTokenDao() {
-        return new PlusSaTokenDao();
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/com/ruoyi/common/satoken/core/dao/PlusSaTokenDao.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/com/ruoyi/common/satoken/core/dao/PlusSaTokenDao.java
deleted file mode 100644
index aafa457..0000000
--- a/ruoyi-common/ruoyi-common-satoken/src/main/java/com/ruoyi/common/satoken/core/dao/PlusSaTokenDao.java
+++ /dev/null
@@ -1,176 +0,0 @@
-package com.ruoyi.common.satoken.core.dao;
-
-import cn.dev33.satoken.dao.SaTokenDao;
-import cn.dev33.satoken.util.SaFoxUtil;
-import com.ruoyi.common.redis.utils.RedisUtils;
-
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * Sa-Token鎸佷箙灞傛帴鍙�(浣跨敤妗嗘灦鑷甫RedisUtils瀹炵幇 鍗忚缁熶竴)
- *
- * @author Lion Li
- */
-public class PlusSaTokenDao implements SaTokenDao {
-
-    /**
-     * 鑾峰彇Value锛屽鏃犺繑绌�
-     */
-    @Override
-    public String get(String key) {
-        return RedisUtils.getCacheObject(key);
-    }
-
-    /**
-     * 鍐欏叆Value锛屽苟璁惧畾瀛樻椿鏃堕棿 (鍗曚綅: 绉�)
-     */
-    @Override
-    public void set(String key, String value, long timeout) {
-        if (timeout == 0 || timeout <= NOT_VALUE_EXPIRE) {
-            return;
-        }
-        // 鍒ゆ柇鏄惁涓烘案涓嶈繃鏈�
-        if (timeout == NEVER_EXPIRE) {
-            RedisUtils.setCacheObject(key, value);
-        } else {
-            RedisUtils.setCacheObject(key, value, Duration.ofSeconds(timeout));
-        }
-    }
-
-    /**
-     * 淇慨鏀规寚瀹歬ey-value閿�煎 (杩囨湡鏃堕棿涓嶅彉)
-     */
-    @Override
-    public void update(String key, String value) {
-        long expire = getTimeout(key);
-        // -2 = 鏃犳閿�
-        if (expire == NOT_VALUE_EXPIRE) {
-            return;
-        }
-        this.set(key, value, expire);
-    }
-
-    /**
-     * 鍒犻櫎Value
-     */
-    @Override
-    public void delete(String key) {
-        RedisUtils.deleteObject(key);
-    }
-
-    /**
-     * 鑾峰彇Value鐨勫墿浣欏瓨娲绘椂闂� (鍗曚綅: 绉�)
-     */
-    @Override
-    public long getTimeout(String key) {
-        long timeout = RedisUtils.getTimeToLive(key);
-        return timeout < 0 ? timeout : timeout / 1000;
-    }
-
-    /**
-     * 淇敼Value鐨勫墿浣欏瓨娲绘椂闂� (鍗曚綅: 绉�)
-     */
-    @Override
-    public void updateTimeout(String key, long timeout) {
-        // 鍒ゆ柇鏄惁鎯宠璁剧疆涓烘案涔�
-        if (timeout == NEVER_EXPIRE) {
-            long expire = getTimeout(key);
-            if (expire == NEVER_EXPIRE) {
-                // 濡傛灉鍏跺凡缁忚璁剧疆涓烘案涔咃紝鍒欎笉浣滀换浣曞鐞�
-            } else {
-                // 濡傛灉灏氭湭琚缃负姘镐箙锛岄偅涔堝啀娆et涓�娆�
-                this.set(key, this.get(key), timeout);
-            }
-            return;
-        }
-        RedisUtils.expire(key, Duration.ofSeconds(timeout));
-    }
-
-
-    /**
-     * 鑾峰彇Object锛屽鏃犺繑绌�
-     */
-    @Override
-    public Object getObject(String key) {
-        return RedisUtils.getCacheObject(key);
-    }
-
-    /**
-     * 鍐欏叆Object锛屽苟璁惧畾瀛樻椿鏃堕棿 (鍗曚綅: 绉�)
-     */
-    @Override
-    public void setObject(String key, Object object, long timeout) {
-        if (timeout == 0 || timeout <= NOT_VALUE_EXPIRE) {
-            return;
-        }
-        // 鍒ゆ柇鏄惁涓烘案涓嶈繃鏈�
-        if (timeout == NEVER_EXPIRE) {
-            RedisUtils.setCacheObject(key, object);
-        } else {
-            RedisUtils.setCacheObject(key, object, Duration.ofSeconds(timeout));
-        }
-    }
-
-    /**
-     * 鏇存柊Object (杩囨湡鏃堕棿涓嶅彉)
-     */
-    @Override
-    public void updateObject(String key, Object object) {
-        long expire = getObjectTimeout(key);
-        // -2 = 鏃犳閿�
-        if (expire == NOT_VALUE_EXPIRE) {
-            return;
-        }
-        this.setObject(key, object, expire);
-    }
-
-    /**
-     * 鍒犻櫎Object
-     */
-    @Override
-    public void deleteObject(String key) {
-        RedisUtils.deleteObject(key);
-    }
-
-    /**
-     * 鑾峰彇Object鐨勫墿浣欏瓨娲绘椂闂� (鍗曚綅: 绉�)
-     */
-    @Override
-    public long getObjectTimeout(String key) {
-        long timeout = RedisUtils.getTimeToLive(key);
-        return timeout < 0 ? timeout : timeout / 1000;
-    }
-
-    /**
-     * 淇敼Object鐨勫墿浣欏瓨娲绘椂闂� (鍗曚綅: 绉�)
-     */
-    @Override
-    public void updateObjectTimeout(String key, long timeout) {
-        // 鍒ゆ柇鏄惁鎯宠璁剧疆涓烘案涔�
-        if (timeout == NEVER_EXPIRE) {
-            long expire = getObjectTimeout(key);
-            if (expire == NEVER_EXPIRE) {
-                // 濡傛灉鍏跺凡缁忚璁剧疆涓烘案涔咃紝鍒欎笉浣滀换浣曞鐞�
-            } else {
-                // 濡傛灉灏氭湭琚缃负姘镐箙锛岄偅涔堝啀娆et涓�娆�
-                this.setObject(key, this.getObject(key), timeout);
-            }
-            return;
-        }
-        RedisUtils.expire(key, Duration.ofSeconds(timeout));
-    }
-
-
-    /**
-     * 鎼滅储鏁版嵁
-     */
-    @Override
-    public List<String> searchData(String prefix, String keyword, int start, int size, boolean sortType) {
-        Collection<String> keys = RedisUtils.keys(prefix + "*" + keyword + "*");
-        List<String> list = new ArrayList<>(keys);
-        return SaFoxUtil.searchList(list, start, size, sortType);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/com/ruoyi/common/satoken/core/service/SaPermissionImpl.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/com/ruoyi/common/satoken/core/service/SaPermissionImpl.java
deleted file mode 100644
index de88738..0000000
--- a/ruoyi-common/ruoyi-common-satoken/src/main/java/com/ruoyi/common/satoken/core/service/SaPermissionImpl.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.ruoyi.common.satoken.core.service;
-
-import cn.dev33.satoken.stp.StpInterface;
-import com.ruoyi.common.core.domain.model.LoginUser;
-import com.ruoyi.common.core.enums.UserType;
-import com.ruoyi.common.satoken.utils.LoginHelper;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * sa-token 鏉冮檺绠$悊瀹炵幇绫�
- *
- * @author Lion Li
- */
-public class SaPermissionImpl implements StpInterface {
-
-    /**
-     * 鑾峰彇鑿滃崟鏉冮檺鍒楄〃
-     */
-    @Override
-    public List<String> getPermissionList(Object loginId, String loginType) {
-        LoginUser loginUser = LoginHelper.getLoginUser();
-        UserType userType = UserType.getUserType(loginUser.getUserType());
-        if (userType == UserType.SYS_USER) {
-            return new ArrayList<>(loginUser.getMenuPermission());
-        } else if (userType == UserType.APP_USER) {
-            // 鍏朵粬绔� 鑷鏍规嵁涓氬姟缂栧啓
-        }
-        return new ArrayList<>();
-    }
-
-    /**
-     * 鑾峰彇瑙掕壊鏉冮檺鍒楄〃
-     */
-    @Override
-    public List<String> getRoleList(Object loginId, String loginType) {
-        LoginUser loginUser = LoginHelper.getLoginUser();
-        UserType userType = UserType.getUserType(loginUser.getUserType());
-        if (userType == UserType.SYS_USER) {
-            return new ArrayList<>(loginUser.getRolePermission());
-        } else if (userType == UserType.APP_USER) {
-            // 鍏朵粬绔� 鑷鏍规嵁涓氬姟缂栧啓
-        }
-        return new ArrayList<>();
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/com/ruoyi/common/satoken/listener/UserActionListener.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/com/ruoyi/common/satoken/listener/UserActionListener.java
deleted file mode 100644
index bcac3b8..0000000
--- a/ruoyi-common/ruoyi-common-satoken/src/main/java/com/ruoyi/common/satoken/listener/UserActionListener.java
+++ /dev/null
@@ -1,139 +0,0 @@
-package com.ruoyi.common.satoken.listener;
-
-import cn.dev33.satoken.config.SaTokenConfig;
-import cn.dev33.satoken.listener.SaTokenListener;
-import cn.dev33.satoken.stp.SaLoginModel;
-import cn.hutool.http.useragent.UserAgent;
-import cn.hutool.http.useragent.UserAgentUtil;
-import com.ruoyi.common.core.constant.CacheConstants;
-import com.ruoyi.common.core.domain.dto.UserOnlineDTO;
-import com.ruoyi.common.core.domain.model.LoginUser;
-import com.ruoyi.common.core.enums.UserType;
-import com.ruoyi.common.redis.utils.RedisUtils;
-import com.ruoyi.common.satoken.utils.LoginHelper;
-import com.ruoyi.common.core.utils.ip.AddressUtils;
-import com.ruoyi.common.core.utils.ServletUtils;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-
-import java.time.Duration;
-
-/**
- * 鐢ㄦ埛琛屼负 渚﹀惉鍣ㄧ殑瀹炵幇
- *
- * @author Lion Li
- */
-@RequiredArgsConstructor
-@Component
-@Slf4j
-public class UserActionListener implements SaTokenListener {
-
-    private final SaTokenConfig tokenConfig;
-
-    /**
-     * 姣忔鐧诲綍鏃惰Е鍙�
-     */
-    @Override
-    public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) {
-        UserType userType = UserType.getUserType(loginId.toString());
-        if (userType == UserType.SYS_USER) {
-            UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"));
-            String ip = ServletUtils.getClientIP();
-            LoginUser user = LoginHelper.getLoginUser();
-            UserOnlineDTO dto = new UserOnlineDTO();
-            dto.setIpaddr(ip);
-            dto.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
-            dto.setBrowser(userAgent.getBrowser().getName());
-            dto.setOs(userAgent.getOs().getName());
-            dto.setLoginTime(System.currentTimeMillis());
-            dto.setTokenId(tokenValue);
-            dto.setUserName(user.getUsername());
-            dto.setDeptName(user.getDeptName());
-            if(tokenConfig.getTimeout() == -1) {
-                RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto);
-            } else {
-                RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto, Duration.ofSeconds(tokenConfig.getTimeout()));
-            }
-            log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue);
-        } else if (userType == UserType.APP_USER) {
-            // app绔� 鑷鏍规嵁涓氬姟缂栧啓
-        }
-    }
-
-    /**
-     * 姣忔娉ㄩ攢鏃惰Е鍙�
-     */
-    @Override
-    public void doLogout(String loginType, Object loginId, String tokenValue) {
-        RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue);
-        log.info("user doLogout, userId:{}, token:{}", loginId, tokenValue);
-    }
-
-    /**
-     * 姣忔琚涪涓嬬嚎鏃惰Е鍙�
-     */
-    @Override
-    public void doKickout(String loginType, Object loginId, String tokenValue) {
-        RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue);
-        log.info("user doKickout, userId:{}, token:{}", loginId, tokenValue);
-    }
-
-    /**
-     * 姣忔琚《涓嬬嚎鏃惰Е鍙�
-     */
-    @Override
-    public void doReplaced(String loginType, Object loginId, String tokenValue) {
-        RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue);
-        log.info("user doReplaced, userId:{}, token:{}", loginId, tokenValue);
-    }
-
-    /**
-     * 姣忔琚皝绂佹椂瑙﹀彂
-     */
-    @Override
-    public void doDisable(String loginType, Object loginId, String service, int level, long disableTime) {
-    }
-
-    /**
-     * 姣忔琚В灏佹椂瑙﹀彂
-     */
-    @Override
-    public void doUntieDisable(String loginType, Object loginId, String service) {
-    }
-
-    /**
-     * 姣忔鎵撳紑浜岀骇璁よ瘉鏃惰Е鍙�
-     */
-    @Override
-    public void doOpenSafe(String loginType, String tokenValue, String service, long safeTime) {
-    }
-
-    /**
-     * 姣忔鍒涘缓Session鏃惰Е鍙�
-     */
-    @Override
-    public void doCloseSafe(String loginType, String tokenValue, String service) {
-    }
-
-    /**
-     * 姣忔鍒涘缓Session鏃惰Е鍙�
-     */
-    @Override
-    public void doCreateSession(String id) {
-    }
-
-    /**
-     * 姣忔娉ㄩ攢Session鏃惰Е鍙�
-     */
-    @Override
-    public void doLogoutSession(String id) {
-    }
-
-    /**
-     * 姣忔Token缁湡鏃惰Е鍙�
-     */
-    @Override
-    public void doRenewTimeout(String tokenValue, Object loginId, long timeout) {
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/com/ruoyi/common/satoken/utils/LoginHelper.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/com/ruoyi/common/satoken/utils/LoginHelper.java
deleted file mode 100644
index cecde85..0000000
--- a/ruoyi-common/ruoyi-common-satoken/src/main/java/com/ruoyi/common/satoken/utils/LoginHelper.java
+++ /dev/null
@@ -1,172 +0,0 @@
-package com.ruoyi.common.satoken.utils;
-
-import cn.dev33.satoken.context.SaHolder;
-import cn.dev33.satoken.context.model.SaStorage;
-import cn.dev33.satoken.stp.SaLoginModel;
-import cn.dev33.satoken.stp.StpUtil;
-import cn.hutool.core.convert.Convert;
-import cn.hutool.core.util.ObjectUtil;
-import com.ruoyi.common.core.constant.TenantConstants;
-import com.ruoyi.common.core.constant.UserConstants;
-import com.ruoyi.common.core.domain.model.LoginUser;
-import com.ruoyi.common.core.enums.DeviceType;
-import com.ruoyi.common.core.enums.UserType;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-
-import java.util.Set;
-
-/**
- * 鐧诲綍閴存潈鍔╂墜
- * <p>
- * user_type 涓� 鐢ㄦ埛绫诲瀷 鍚屼竴涓敤鎴疯〃 鍙互鏈夊绉嶇敤鎴风被鍨� 渚嬪 pc,app
- * deivce 涓� 璁惧绫诲瀷 鍚屼竴涓敤鎴风被鍨� 鍙互鏈� 澶氱璁惧绫诲瀷 渚嬪 web,ios
- * 鍙互缁勬垚 鐢ㄦ埛绫诲瀷涓庤澶囩被鍨嬪瀵瑰鐨� 鏉冮檺鐏垫椿鎺у埗
- * <p>
- * 澶氱敤鎴蜂綋绯� 閽堝 澶氱鐢ㄦ埛绫诲瀷 浣嗘潈闄愭帶鍒朵笉涓�鑷�
- * 鍙互缁勬垚 澶氱敤鎴风被鍨嬭〃涓庡璁惧绫诲瀷 鍒嗗埆鎺у埗鏉冮檺
- *
- * @author Lion Li
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class LoginHelper {
-
-    public static final String LOGIN_USER_KEY = "loginUser";
-    public static final String TENANT_KEY = "tenantId";
-    public static final String USER_KEY = "userId";
-
-    /**
-     * 鐧诲綍绯荤粺
-     *
-     * @param loginUser 鐧诲綍鐢ㄦ埛淇℃伅
-     */
-    public static void login(LoginUser loginUser) {
-        loginByDevice(loginUser, null);
-    }
-
-    /**
-     * 鐧诲綍绯荤粺 鍩轰簬 璁惧绫诲瀷
-     * 閽堝鐩稿悓鐢ㄦ埛浣撶郴涓嶅悓璁惧
-     *
-     * @param loginUser 鐧诲綍鐢ㄦ埛淇℃伅
-     */
-    public static void loginByDevice(LoginUser loginUser, DeviceType deviceType) {
-        SaStorage storage = SaHolder.getStorage();
-        storage.set(LOGIN_USER_KEY, loginUser);
-        storage.set(TENANT_KEY, loginUser.getTenantId());
-        storage.set(USER_KEY, loginUser.getUserId());
-        SaLoginModel model = new SaLoginModel();
-        if (ObjectUtil.isNotNull(deviceType)) {
-            model.setDevice(deviceType.getDevice());
-        }
-        StpUtil.login(loginUser.getLoginId(),
-            model.setExtra(TENANT_KEY, loginUser.getTenantId())
-                .setExtra(USER_KEY, loginUser.getUserId()));
-        StpUtil.getTokenSession().set(LOGIN_USER_KEY, loginUser);
-    }
-
-    /**
-     * 鑾峰彇鐢ㄦ埛(澶氱骇缂撳瓨)
-     */
-    public static LoginUser getLoginUser() {
-        LoginUser loginUser = (LoginUser) SaHolder.getStorage().get(LOGIN_USER_KEY);
-        if (loginUser != null) {
-            return loginUser;
-        }
-        loginUser = (LoginUser) StpUtil.getTokenSession().get(LOGIN_USER_KEY);
-        SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser);
-        return loginUser;
-    }
-
-    /**
-     * 鑾峰彇鐢ㄦ埛鍩轰簬token
-     */
-    public static LoginUser getLoginUser(String token) {
-        return (LoginUser) StpUtil.getTokenSessionByToken(token).get(LOGIN_USER_KEY);
-    }
-
-    /**
-     * 鑾峰彇鐢ㄦ埛id
-     */
-    public static Long getUserId() {
-        Long userId;
-        try {
-            userId = Convert.toLong(SaHolder.getStorage().get(USER_KEY));
-            if (ObjectUtil.isNull(userId)) {
-                userId = Convert.toLong(StpUtil.getExtra(USER_KEY));
-                SaHolder.getStorage().set(USER_KEY, userId);
-            }
-        } catch (Exception e) {
-            return null;
-        }
-        return userId;
-    }
-
-    /**
-     * 鑾峰彇绉熸埛ID
-     */
-    public static String getTenantId() {
-        String tenantId;
-        try {
-            tenantId = (String) SaHolder.getStorage().get(TENANT_KEY);
-            if (ObjectUtil.isNull(tenantId)) {
-                tenantId = (String) StpUtil.getExtra(TENANT_KEY);
-                SaHolder.getStorage().set(TENANT_KEY, tenantId);
-            }
-        } catch (Exception e) {
-            return null;
-        }
-        return tenantId;
-    }
-
-    /**
-     * 鑾峰彇閮ㄩ棬ID
-     */
-    public static Long getDeptId() {
-        return getLoginUser().getDeptId();
-    }
-
-    /**
-     * 鑾峰彇鐢ㄦ埛璐︽埛
-     */
-    public static String getUsername() {
-        return getLoginUser().getUsername();
-    }
-
-    /**
-     * 鑾峰彇鐢ㄦ埛绫诲瀷
-     */
-    public static UserType getUserType() {
-        String loginId = StpUtil.getLoginIdAsString();
-        return UserType.getUserType(loginId);
-    }
-
-    /**
-     * 鏄惁涓鸿秴绾х鐞嗗憳
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 缁撴灉
-     */
-    public static boolean isSuperAdmin(Long userId) {
-        return UserConstants.SUPER_ADMIN_ID.equals(userId);
-    }
-
-    public static boolean isSuperAdmin() {
-        return isSuperAdmin(getUserId());
-    }
-
-    /**
-     * 鏄惁涓鸿秴绾х鐞嗗憳
-     *
-     * @param rolePermission 瑙掕壊鏉冮檺鏍囪瘑缁�
-     * @return 缁撴灉
-     */
-    public static boolean isTenantAdmin(Set<String> rolePermission) {
-        return rolePermission.contains(TenantConstants.TENANT_ADMIN_ROLE_KEY);
-    }
-
-    public static boolean isTenantAdmin() {
-        return isTenantAdmin(getLoginUser().getRolePermission());
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/config/SaTokenConfig.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/config/SaTokenConfig.java
new file mode 100644
index 0000000..54ae2da
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/config/SaTokenConfig.java
@@ -0,0 +1,43 @@
+package org.dromara.common.satoken.config;
+
+import cn.dev33.satoken.dao.SaTokenDao;
+import cn.dev33.satoken.jwt.StpLogicJwtForSimple;
+import cn.dev33.satoken.stp.StpInterface;
+import cn.dev33.satoken.stp.StpLogic;
+import org.dromara.common.satoken.core.dao.PlusSaTokenDao;
+import org.dromara.common.satoken.core.service.SaPermissionImpl;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * sa-token 閰嶇疆
+ *
+ * @author Lion Li
+ */
+@AutoConfiguration
+public class SaTokenConfig implements WebMvcConfigurer {
+
+    @Bean
+    public StpLogic getStpLogicJwt() {
+        // Sa-Token 鏁村悎 jwt (绠�鍗曟ā寮�)
+        return new StpLogicJwtForSimple();
+    }
+
+    /**
+     * 鏉冮檺鎺ュ彛瀹炵幇(浣跨敤bean娉ㄥ叆鏂逛究鐢ㄦ埛鏇挎崲)
+     */
+    @Bean
+    public StpInterface stpInterface() {
+        return new SaPermissionImpl();
+    }
+
+    /**
+     * 鑷畾涔塪ao灞傚瓨鍌�
+     */
+    @Bean
+    public SaTokenDao saTokenDao() {
+        return new PlusSaTokenDao();
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java
new file mode 100644
index 0000000..8d2aac9
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java
@@ -0,0 +1,176 @@
+package org.dromara.common.satoken.core.dao;
+
+import cn.dev33.satoken.dao.SaTokenDao;
+import cn.dev33.satoken.util.SaFoxUtil;
+import org.dromara.common.redis.utils.RedisUtils;
+
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Sa-Token鎸佷箙灞傛帴鍙�(浣跨敤妗嗘灦鑷甫RedisUtils瀹炵幇 鍗忚缁熶竴)
+ *
+ * @author Lion Li
+ */
+public class PlusSaTokenDao implements SaTokenDao {
+
+    /**
+     * 鑾峰彇Value锛屽鏃犺繑绌�
+     */
+    @Override
+    public String get(String key) {
+        return RedisUtils.getCacheObject(key);
+    }
+
+    /**
+     * 鍐欏叆Value锛屽苟璁惧畾瀛樻椿鏃堕棿 (鍗曚綅: 绉�)
+     */
+    @Override
+    public void set(String key, String value, long timeout) {
+        if (timeout == 0 || timeout <= NOT_VALUE_EXPIRE) {
+            return;
+        }
+        // 鍒ゆ柇鏄惁涓烘案涓嶈繃鏈�
+        if (timeout == NEVER_EXPIRE) {
+            RedisUtils.setCacheObject(key, value);
+        } else {
+            RedisUtils.setCacheObject(key, value, Duration.ofSeconds(timeout));
+        }
+    }
+
+    /**
+     * 淇慨鏀规寚瀹歬ey-value閿�煎 (杩囨湡鏃堕棿涓嶅彉)
+     */
+    @Override
+    public void update(String key, String value) {
+        long expire = getTimeout(key);
+        // -2 = 鏃犳閿�
+        if (expire == NOT_VALUE_EXPIRE) {
+            return;
+        }
+        this.set(key, value, expire);
+    }
+
+    /**
+     * 鍒犻櫎Value
+     */
+    @Override
+    public void delete(String key) {
+        RedisUtils.deleteObject(key);
+    }
+
+    /**
+     * 鑾峰彇Value鐨勫墿浣欏瓨娲绘椂闂� (鍗曚綅: 绉�)
+     */
+    @Override
+    public long getTimeout(String key) {
+        long timeout = RedisUtils.getTimeToLive(key);
+        return timeout < 0 ? timeout : timeout / 1000;
+    }
+
+    /**
+     * 淇敼Value鐨勫墿浣欏瓨娲绘椂闂� (鍗曚綅: 绉�)
+     */
+    @Override
+    public void updateTimeout(String key, long timeout) {
+        // 鍒ゆ柇鏄惁鎯宠璁剧疆涓烘案涔�
+        if (timeout == NEVER_EXPIRE) {
+            long expire = getTimeout(key);
+            if (expire == NEVER_EXPIRE) {
+                // 濡傛灉鍏跺凡缁忚璁剧疆涓烘案涔咃紝鍒欎笉浣滀换浣曞鐞�
+            } else {
+                // 濡傛灉灏氭湭琚缃负姘镐箙锛岄偅涔堝啀娆et涓�娆�
+                this.set(key, this.get(key), timeout);
+            }
+            return;
+        }
+        RedisUtils.expire(key, Duration.ofSeconds(timeout));
+    }
+
+
+    /**
+     * 鑾峰彇Object锛屽鏃犺繑绌�
+     */
+    @Override
+    public Object getObject(String key) {
+        return RedisUtils.getCacheObject(key);
+    }
+
+    /**
+     * 鍐欏叆Object锛屽苟璁惧畾瀛樻椿鏃堕棿 (鍗曚綅: 绉�)
+     */
+    @Override
+    public void setObject(String key, Object object, long timeout) {
+        if (timeout == 0 || timeout <= NOT_VALUE_EXPIRE) {
+            return;
+        }
+        // 鍒ゆ柇鏄惁涓烘案涓嶈繃鏈�
+        if (timeout == NEVER_EXPIRE) {
+            RedisUtils.setCacheObject(key, object);
+        } else {
+            RedisUtils.setCacheObject(key, object, Duration.ofSeconds(timeout));
+        }
+    }
+
+    /**
+     * 鏇存柊Object (杩囨湡鏃堕棿涓嶅彉)
+     */
+    @Override
+    public void updateObject(String key, Object object) {
+        long expire = getObjectTimeout(key);
+        // -2 = 鏃犳閿�
+        if (expire == NOT_VALUE_EXPIRE) {
+            return;
+        }
+        this.setObject(key, object, expire);
+    }
+
+    /**
+     * 鍒犻櫎Object
+     */
+    @Override
+    public void deleteObject(String key) {
+        RedisUtils.deleteObject(key);
+    }
+
+    /**
+     * 鑾峰彇Object鐨勫墿浣欏瓨娲绘椂闂� (鍗曚綅: 绉�)
+     */
+    @Override
+    public long getObjectTimeout(String key) {
+        long timeout = RedisUtils.getTimeToLive(key);
+        return timeout < 0 ? timeout : timeout / 1000;
+    }
+
+    /**
+     * 淇敼Object鐨勫墿浣欏瓨娲绘椂闂� (鍗曚綅: 绉�)
+     */
+    @Override
+    public void updateObjectTimeout(String key, long timeout) {
+        // 鍒ゆ柇鏄惁鎯宠璁剧疆涓烘案涔�
+        if (timeout == NEVER_EXPIRE) {
+            long expire = getObjectTimeout(key);
+            if (expire == NEVER_EXPIRE) {
+                // 濡傛灉鍏跺凡缁忚璁剧疆涓烘案涔咃紝鍒欎笉浣滀换浣曞鐞�
+            } else {
+                // 濡傛灉灏氭湭琚缃负姘镐箙锛岄偅涔堝啀娆et涓�娆�
+                this.setObject(key, this.getObject(key), timeout);
+            }
+            return;
+        }
+        RedisUtils.expire(key, Duration.ofSeconds(timeout));
+    }
+
+
+    /**
+     * 鎼滅储鏁版嵁
+     */
+    @Override
+    public List<String> searchData(String prefix, String keyword, int start, int size, boolean sortType) {
+        Collection<String> keys = RedisUtils.keys(prefix + "*" + keyword + "*");
+        List<String> list = new ArrayList<>(keys);
+        return SaFoxUtil.searchList(list, start, size, sortType);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/service/SaPermissionImpl.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/service/SaPermissionImpl.java
new file mode 100644
index 0000000..1cef9a7
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/service/SaPermissionImpl.java
@@ -0,0 +1,47 @@
+package org.dromara.common.satoken.core.service;
+
+import cn.dev33.satoken.stp.StpInterface;
+import org.dromara.common.core.domain.model.LoginUser;
+import org.dromara.common.core.enums.UserType;
+import org.dromara.common.satoken.utils.LoginHelper;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * sa-token 鏉冮檺绠$悊瀹炵幇绫�
+ *
+ * @author Lion Li
+ */
+public class SaPermissionImpl implements StpInterface {
+
+    /**
+     * 鑾峰彇鑿滃崟鏉冮檺鍒楄〃
+     */
+    @Override
+    public List<String> getPermissionList(Object loginId, String loginType) {
+        LoginUser loginUser = LoginHelper.getLoginUser();
+        UserType userType = UserType.getUserType(loginUser.getUserType());
+        if (userType == UserType.SYS_USER) {
+            return new ArrayList<>(loginUser.getMenuPermission());
+        } else if (userType == UserType.APP_USER) {
+            // 鍏朵粬绔� 鑷鏍规嵁涓氬姟缂栧啓
+        }
+        return new ArrayList<>();
+    }
+
+    /**
+     * 鑾峰彇瑙掕壊鏉冮檺鍒楄〃
+     */
+    @Override
+    public List<String> getRoleList(Object loginId, String loginType) {
+        LoginUser loginUser = LoginHelper.getLoginUser();
+        UserType userType = UserType.getUserType(loginUser.getUserType());
+        if (userType == UserType.SYS_USER) {
+            return new ArrayList<>(loginUser.getRolePermission());
+        } else if (userType == UserType.APP_USER) {
+            // 鍏朵粬绔� 鑷鏍规嵁涓氬姟缂栧啓
+        }
+        return new ArrayList<>();
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/listener/UserActionListener.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/listener/UserActionListener.java
new file mode 100644
index 0000000..11245e0
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/listener/UserActionListener.java
@@ -0,0 +1,139 @@
+package org.dromara.common.satoken.listener;
+
+import cn.dev33.satoken.config.SaTokenConfig;
+import cn.dev33.satoken.listener.SaTokenListener;
+import cn.dev33.satoken.stp.SaLoginModel;
+import cn.hutool.http.useragent.UserAgent;
+import cn.hutool.http.useragent.UserAgentUtil;
+import org.dromara.common.core.constant.CacheConstants;
+import org.dromara.common.core.domain.dto.UserOnlineDTO;
+import org.dromara.common.core.domain.model.LoginUser;
+import org.dromara.common.core.enums.UserType;
+import org.dromara.common.redis.utils.RedisUtils;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.common.core.utils.ip.AddressUtils;
+import org.dromara.common.core.utils.ServletUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.time.Duration;
+
+/**
+ * 鐢ㄦ埛琛屼负 渚﹀惉鍣ㄧ殑瀹炵幇
+ *
+ * @author Lion Li
+ */
+@RequiredArgsConstructor
+@Component
+@Slf4j
+public class UserActionListener implements SaTokenListener {
+
+    private final SaTokenConfig tokenConfig;
+
+    /**
+     * 姣忔鐧诲綍鏃惰Е鍙�
+     */
+    @Override
+    public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) {
+        UserType userType = UserType.getUserType(loginId.toString());
+        if (userType == UserType.SYS_USER) {
+            UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"));
+            String ip = ServletUtils.getClientIP();
+            LoginUser user = LoginHelper.getLoginUser();
+            UserOnlineDTO dto = new UserOnlineDTO();
+            dto.setIpaddr(ip);
+            dto.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
+            dto.setBrowser(userAgent.getBrowser().getName());
+            dto.setOs(userAgent.getOs().getName());
+            dto.setLoginTime(System.currentTimeMillis());
+            dto.setTokenId(tokenValue);
+            dto.setUserName(user.getUsername());
+            dto.setDeptName(user.getDeptName());
+            if(tokenConfig.getTimeout() == -1) {
+                RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto);
+            } else {
+                RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto, Duration.ofSeconds(tokenConfig.getTimeout()));
+            }
+            log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue);
+        } else if (userType == UserType.APP_USER) {
+            // app绔� 鑷鏍规嵁涓氬姟缂栧啓
+        }
+    }
+
+    /**
+     * 姣忔娉ㄩ攢鏃惰Е鍙�
+     */
+    @Override
+    public void doLogout(String loginType, Object loginId, String tokenValue) {
+        RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue);
+        log.info("user doLogout, userId:{}, token:{}", loginId, tokenValue);
+    }
+
+    /**
+     * 姣忔琚涪涓嬬嚎鏃惰Е鍙�
+     */
+    @Override
+    public void doKickout(String loginType, Object loginId, String tokenValue) {
+        RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue);
+        log.info("user doKickout, userId:{}, token:{}", loginId, tokenValue);
+    }
+
+    /**
+     * 姣忔琚《涓嬬嚎鏃惰Е鍙�
+     */
+    @Override
+    public void doReplaced(String loginType, Object loginId, String tokenValue) {
+        RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue);
+        log.info("user doReplaced, userId:{}, token:{}", loginId, tokenValue);
+    }
+
+    /**
+     * 姣忔琚皝绂佹椂瑙﹀彂
+     */
+    @Override
+    public void doDisable(String loginType, Object loginId, String service, int level, long disableTime) {
+    }
+
+    /**
+     * 姣忔琚В灏佹椂瑙﹀彂
+     */
+    @Override
+    public void doUntieDisable(String loginType, Object loginId, String service) {
+    }
+
+    /**
+     * 姣忔鎵撳紑浜岀骇璁よ瘉鏃惰Е鍙�
+     */
+    @Override
+    public void doOpenSafe(String loginType, String tokenValue, String service, long safeTime) {
+    }
+
+    /**
+     * 姣忔鍒涘缓Session鏃惰Е鍙�
+     */
+    @Override
+    public void doCloseSafe(String loginType, String tokenValue, String service) {
+    }
+
+    /**
+     * 姣忔鍒涘缓Session鏃惰Е鍙�
+     */
+    @Override
+    public void doCreateSession(String id) {
+    }
+
+    /**
+     * 姣忔娉ㄩ攢Session鏃惰Е鍙�
+     */
+    @Override
+    public void doLogoutSession(String id) {
+    }
+
+    /**
+     * 姣忔Token缁湡鏃惰Е鍙�
+     */
+    @Override
+    public void doRenewTimeout(String tokenValue, Object loginId, long timeout) {
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java
new file mode 100644
index 0000000..e79b9ba
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java
@@ -0,0 +1,172 @@
+package org.dromara.common.satoken.utils;
+
+import cn.dev33.satoken.context.SaHolder;
+import cn.dev33.satoken.context.model.SaStorage;
+import cn.dev33.satoken.stp.SaLoginModel;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.ObjectUtil;
+import org.dromara.common.core.constant.TenantConstants;
+import org.dromara.common.core.constant.UserConstants;
+import org.dromara.common.core.domain.model.LoginUser;
+import org.dromara.common.core.enums.DeviceType;
+import org.dromara.common.core.enums.UserType;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import java.util.Set;
+
+/**
+ * 鐧诲綍閴存潈鍔╂墜
+ * <p>
+ * user_type 涓� 鐢ㄦ埛绫诲瀷 鍚屼竴涓敤鎴疯〃 鍙互鏈夊绉嶇敤鎴风被鍨� 渚嬪 pc,app
+ * deivce 涓� 璁惧绫诲瀷 鍚屼竴涓敤鎴风被鍨� 鍙互鏈� 澶氱璁惧绫诲瀷 渚嬪 web,ios
+ * 鍙互缁勬垚 鐢ㄦ埛绫诲瀷涓庤澶囩被鍨嬪瀵瑰鐨� 鏉冮檺鐏垫椿鎺у埗
+ * <p>
+ * 澶氱敤鎴蜂綋绯� 閽堝 澶氱鐢ㄦ埛绫诲瀷 浣嗘潈闄愭帶鍒朵笉涓�鑷�
+ * 鍙互缁勬垚 澶氱敤鎴风被鍨嬭〃涓庡璁惧绫诲瀷 鍒嗗埆鎺у埗鏉冮檺
+ *
+ * @author Lion Li
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class LoginHelper {
+
+    public static final String LOGIN_USER_KEY = "loginUser";
+    public static final String TENANT_KEY = "tenantId";
+    public static final String USER_KEY = "userId";
+
+    /**
+     * 鐧诲綍绯荤粺
+     *
+     * @param loginUser 鐧诲綍鐢ㄦ埛淇℃伅
+     */
+    public static void login(LoginUser loginUser) {
+        loginByDevice(loginUser, null);
+    }
+
+    /**
+     * 鐧诲綍绯荤粺 鍩轰簬 璁惧绫诲瀷
+     * 閽堝鐩稿悓鐢ㄦ埛浣撶郴涓嶅悓璁惧
+     *
+     * @param loginUser 鐧诲綍鐢ㄦ埛淇℃伅
+     */
+    public static void loginByDevice(LoginUser loginUser, DeviceType deviceType) {
+        SaStorage storage = SaHolder.getStorage();
+        storage.set(LOGIN_USER_KEY, loginUser);
+        storage.set(TENANT_KEY, loginUser.getTenantId());
+        storage.set(USER_KEY, loginUser.getUserId());
+        SaLoginModel model = new SaLoginModel();
+        if (ObjectUtil.isNotNull(deviceType)) {
+            model.setDevice(deviceType.getDevice());
+        }
+        StpUtil.login(loginUser.getLoginId(),
+            model.setExtra(TENANT_KEY, loginUser.getTenantId())
+                .setExtra(USER_KEY, loginUser.getUserId()));
+        StpUtil.getTokenSession().set(LOGIN_USER_KEY, loginUser);
+    }
+
+    /**
+     * 鑾峰彇鐢ㄦ埛(澶氱骇缂撳瓨)
+     */
+    public static LoginUser getLoginUser() {
+        LoginUser loginUser = (LoginUser) SaHolder.getStorage().get(LOGIN_USER_KEY);
+        if (loginUser != null) {
+            return loginUser;
+        }
+        loginUser = (LoginUser) StpUtil.getTokenSession().get(LOGIN_USER_KEY);
+        SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser);
+        return loginUser;
+    }
+
+    /**
+     * 鑾峰彇鐢ㄦ埛鍩轰簬token
+     */
+    public static LoginUser getLoginUser(String token) {
+        return (LoginUser) StpUtil.getTokenSessionByToken(token).get(LOGIN_USER_KEY);
+    }
+
+    /**
+     * 鑾峰彇鐢ㄦ埛id
+     */
+    public static Long getUserId() {
+        Long userId;
+        try {
+            userId = Convert.toLong(SaHolder.getStorage().get(USER_KEY));
+            if (ObjectUtil.isNull(userId)) {
+                userId = Convert.toLong(StpUtil.getExtra(USER_KEY));
+                SaHolder.getStorage().set(USER_KEY, userId);
+            }
+        } catch (Exception e) {
+            return null;
+        }
+        return userId;
+    }
+
+    /**
+     * 鑾峰彇绉熸埛ID
+     */
+    public static String getTenantId() {
+        String tenantId;
+        try {
+            tenantId = (String) SaHolder.getStorage().get(TENANT_KEY);
+            if (ObjectUtil.isNull(tenantId)) {
+                tenantId = (String) StpUtil.getExtra(TENANT_KEY);
+                SaHolder.getStorage().set(TENANT_KEY, tenantId);
+            }
+        } catch (Exception e) {
+            return null;
+        }
+        return tenantId;
+    }
+
+    /**
+     * 鑾峰彇閮ㄩ棬ID
+     */
+    public static Long getDeptId() {
+        return getLoginUser().getDeptId();
+    }
+
+    /**
+     * 鑾峰彇鐢ㄦ埛璐︽埛
+     */
+    public static String getUsername() {
+        return getLoginUser().getUsername();
+    }
+
+    /**
+     * 鑾峰彇鐢ㄦ埛绫诲瀷
+     */
+    public static UserType getUserType() {
+        String loginId = StpUtil.getLoginIdAsString();
+        return UserType.getUserType(loginId);
+    }
+
+    /**
+     * 鏄惁涓鸿秴绾х鐞嗗憳
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 缁撴灉
+     */
+    public static boolean isSuperAdmin(Long userId) {
+        return UserConstants.SUPER_ADMIN_ID.equals(userId);
+    }
+
+    public static boolean isSuperAdmin() {
+        return isSuperAdmin(getUserId());
+    }
+
+    /**
+     * 鏄惁涓鸿秴绾х鐞嗗憳
+     *
+     * @param rolePermission 瑙掕壊鏉冮檺鏍囪瘑缁�
+     * @return 缁撴灉
+     */
+    public static boolean isTenantAdmin(Set<String> rolePermission) {
+        return rolePermission.contains(TenantConstants.TENANT_ADMIN_ROLE_KEY);
+    }
+
+    public static boolean isTenantAdmin() {
+        return isTenantAdmin(getLoginUser().getRolePermission());
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-satoken/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index d358acb..6dd284f 100644
--- a/ruoyi-common/ruoyi-common-satoken/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-common/ruoyi-common-satoken/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +1 @@
-com.ruoyi.common.satoken.config.SaTokenConfig
+org.dromara.common.satoken.config.SaTokenConfig
diff --git a/ruoyi-common/ruoyi-common-security/pom.xml b/ruoyi-common/ruoyi-common-security/pom.xml
index 1cc554b..74b5363 100644
--- a/ruoyi-common/ruoyi-common-security/pom.xml
+++ b/ruoyi-common/ruoyi-common-security/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-common</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -18,7 +18,7 @@
 
     <dependencies>
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-satoken</artifactId>
         </dependency>
 
diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/config/SecurityConfig.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/config/SecurityConfig.java
deleted file mode 100644
index b4fa6ba..0000000
--- a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/config/SecurityConfig.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.ruoyi.common.security.config;
-
-import cn.dev33.satoken.interceptor.SaInterceptor;
-import cn.dev33.satoken.router.SaRouter;
-import cn.dev33.satoken.stp.StpUtil;
-import com.ruoyi.common.core.utils.SpringUtils;
-import com.ruoyi.common.security.config.properties.SecurityProperties;
-import com.ruoyi.common.security.handler.AllUrlHandler;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
-/**
- * 鏉冮檺瀹夊叏閰嶇疆
- *
- * @author Lion Li
- */
-
-@Slf4j
-@AutoConfiguration
-@EnableConfigurationProperties(SecurityProperties.class)
-@RequiredArgsConstructor
-public class SecurityConfig implements WebMvcConfigurer {
-
-    private final SecurityProperties securityProperties;
-
-    /**
-     * 娉ㄥ唽sa-token鐨勬嫤鎴櫒
-     */
-    @Override
-    public void addInterceptors(InterceptorRegistry registry) {
-        // 娉ㄥ唽璺敱鎷︽埅鍣紝鑷畾涔夐獙璇佽鍒�
-        registry.addInterceptor(new SaInterceptor(handler -> {
-            AllUrlHandler allUrlHandler = SpringUtils.getBean(AllUrlHandler.class);
-            // 鐧诲綍楠岃瘉 -- 鎺掗櫎澶氫釜璺緞
-            SaRouter
-                // 鑾峰彇鎵�鏈夌殑
-                .match(allUrlHandler.getUrls())
-                // 瀵规湭鎺掗櫎鐨勮矾寰勮繘琛屾鏌�
-                .check(() -> {
-                    // 妫�鏌ユ槸鍚︾櫥褰� 鏄惁鏈塼oken
-                    StpUtil.checkLogin();
-
-                    // 鏈夋晥鐜囧奖鍝� 鐢ㄤ簬涓存椂娴嬭瘯
-                    // if (log.isDebugEnabled()) {
-                    //     log.debug("鍓╀綑鏈夋晥鏃堕棿: {}", StpUtil.getTokenTimeout());
-                    //     log.debug("涓存椂鏈夋晥鏃堕棿: {}", StpUtil.getTokenActivityTimeout());
-                    // }
-
-                });
-        })).addPathPatterns("/**")
-            // 鎺掗櫎涓嶉渶瑕佹嫤鎴殑璺緞
-            .excludePathPatterns(securityProperties.getExcludes());
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/config/properties/SecurityProperties.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/config/properties/SecurityProperties.java
deleted file mode 100644
index 109a89c..0000000
--- a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/config/properties/SecurityProperties.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.ruoyi.common.security.config.properties;
-
-import lombok.Data;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-/**
- * Security 閰嶇疆灞炴��
- *
- * @author Lion Li
- */
-@Data
-@ConfigurationProperties(prefix = "security")
-public class SecurityProperties {
-
-    /**
-     * 鎺掗櫎璺緞
-     */
-    private String[] excludes;
-
-
-}
diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/AllUrlHandler.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/AllUrlHandler.java
deleted file mode 100644
index cf58172..0000000
--- a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/AllUrlHandler.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.ruoyi.common.security.handler;
-
-import cn.hutool.core.util.ReUtil;
-import com.ruoyi.common.core.utils.SpringUtils;
-import lombok.Data;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.web.method.HandlerMethod;
-import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
-import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
-
-import java.util.*;
-import java.util.regex.Pattern;
-
-/**
- * 鑾峰彇鎵�鏈塙rl閰嶇疆
- *
- * @author Lion Li
- */
-@Data
-public class AllUrlHandler implements InitializingBean {
-
-    private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}");
-
-    private List<String> urls = new ArrayList<>();
-
-    @Override
-    public void afterPropertiesSet() {
-        Set<String> set = new HashSet<>();
-        RequestMappingHandlerMapping mapping = SpringUtils.getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class);
-        Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();
-        map.keySet().forEach(info -> {
-            // 鑾峰彇娉ㄨВ涓婅竟鐨� path 鏇夸唬 path variable 涓� *
-            Objects.requireNonNull(info.getPathPatternsCondition().getPatterns())
-                    .forEach(url -> set.add(ReUtil.replaceAll(url.getPatternString(), PATTERN, "*")));
-        });
-        urls.addAll(set);
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/GlobalExceptionHandler.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/GlobalExceptionHandler.java
deleted file mode 100644
index f8f0041..0000000
--- a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/GlobalExceptionHandler.java
+++ /dev/null
@@ -1,141 +0,0 @@
-package com.ruoyi.common.security.handler;
-
-import cn.dev33.satoken.exception.NotLoginException;
-import cn.dev33.satoken.exception.NotPermissionException;
-import cn.dev33.satoken.exception.NotRoleException;
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.http.HttpStatus;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.core.exception.DemoModeException;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.utils.StreamUtils;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.context.support.DefaultMessageSourceResolvable;
-import org.springframework.validation.BindException;
-import org.springframework.web.HttpRequestMethodNotSupportedException;
-import org.springframework.web.bind.MethodArgumentNotValidException;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.bind.annotation.RestControllerAdvice;
-
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.validation.ConstraintViolation;
-import jakarta.validation.ConstraintViolationException;
-
-/**
- * 鍏ㄥ眬寮傚父澶勭悊鍣�
- *
- * @author Lion Li
- */
-@Slf4j
-@RestControllerAdvice
-public class GlobalExceptionHandler {
-
-    /**
-     * 鏉冮檺鐮佸紓甯�
-     */
-    @ExceptionHandler(NotPermissionException.class)
-    public R<Void> handleNotPermissionException(NotPermissionException e, HttpServletRequest request) {
-        String requestURI = request.getRequestURI();
-        log.error("璇锋眰鍦板潃'{}',鏉冮檺鐮佹牎楠屽け璐�'{}'", requestURI, e.getMessage());
-        return R.fail(HttpStatus.HTTP_FORBIDDEN, "娌℃湁璁块棶鏉冮檺锛岃鑱旂郴绠$悊鍛樻巿鏉�");
-    }
-
-    /**
-     * 瑙掕壊鏉冮檺寮傚父
-     */
-    @ExceptionHandler(NotRoleException.class)
-    public R<Void> handleNotRoleException(NotRoleException e, HttpServletRequest request) {
-        String requestURI = request.getRequestURI();
-        log.error("璇锋眰鍦板潃'{}',瑙掕壊鏉冮檺鏍¢獙澶辫触'{}'", requestURI, e.getMessage());
-        return R.fail(HttpStatus.HTTP_FORBIDDEN, "娌℃湁璁块棶鏉冮檺锛岃鑱旂郴绠$悊鍛樻巿鏉�");
-    }
-
-    /**
-     * 璁よ瘉澶辫触
-     */
-    @ExceptionHandler(NotLoginException.class)
-    public R<Void> handleNotLoginException(NotLoginException e, HttpServletRequest request) {
-        String requestURI = request.getRequestURI();
-        log.error("璇锋眰鍦板潃'{}',璁よ瘉澶辫触'{}',鏃犳硶璁块棶绯荤粺璧勬簮", requestURI, e.getMessage());
-        return R.fail(HttpStatus.HTTP_UNAUTHORIZED, "璁よ瘉澶辫触锛屾棤娉曡闂郴缁熻祫婧�");
-    }
-
-    /**
-     * 璇锋眰鏂瑰紡涓嶆敮鎸�
-     */
-    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
-    public R<Void> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,
-                                                                HttpServletRequest request) {
-        String requestURI = request.getRequestURI();
-        log.error("璇锋眰鍦板潃'{}',涓嶆敮鎸�'{}'璇锋眰", requestURI, e.getMethod());
-        return R.fail(e.getMessage());
-    }
-
-    /**
-     * 涓氬姟寮傚父
-     */
-    @ExceptionHandler(ServiceException.class)
-    public R<Void> handleServiceException(ServiceException e, HttpServletRequest request) {
-        log.error(e.getMessage(), e);
-        Integer code = e.getCode();
-        return ObjectUtil.isNotNull(code) ? R.fail(code, e.getMessage()) : R.fail(e.getMessage());
-    }
-
-    /**
-     * 鎷︽埅鏈煡鐨勮繍琛屾椂寮傚父
-     */
-    @ExceptionHandler(RuntimeException.class)
-    public R<Void> handleRuntimeException(RuntimeException e, HttpServletRequest request) {
-        String requestURI = request.getRequestURI();
-        log.error("璇锋眰鍦板潃'{}',鍙戠敓鏈煡寮傚父.", requestURI, e);
-        return R.fail(e.getMessage());
-    }
-
-    /**
-     * 绯荤粺寮傚父
-     */
-    @ExceptionHandler(Exception.class)
-    public R<Void> handleException(Exception e, HttpServletRequest request) {
-        String requestURI = request.getRequestURI();
-        log.error("璇锋眰鍦板潃'{}',鍙戠敓绯荤粺寮傚父.", requestURI, e);
-        return R.fail(e.getMessage());
-    }
-
-    /**
-     * 鑷畾涔夐獙璇佸紓甯�
-     */
-    @ExceptionHandler(BindException.class)
-    public R<Void> handleBindException(BindException e) {
-        log.error(e.getMessage(), e);
-        String message = StreamUtils.join(e.getAllErrors(), DefaultMessageSourceResolvable::getDefaultMessage, ", ");
-        return R.fail(message);
-    }
-
-    /**
-     * 鑷畾涔夐獙璇佸紓甯�
-     */
-    @ExceptionHandler(ConstraintViolationException.class)
-    public R<Void> constraintViolationException(ConstraintViolationException e) {
-        log.error(e.getMessage(), e);
-        String message = StreamUtils.join(e.getConstraintViolations(), ConstraintViolation::getMessage, ", ");
-        return R.fail(message);
-    }
-
-    /**
-     * 鑷畾涔夐獙璇佸紓甯�
-     */
-    @ExceptionHandler(MethodArgumentNotValidException.class)
-    public R<Void> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
-        log.error(e.getMessage(), e);
-        String message = e.getBindingResult().getFieldError().getDefaultMessage();
-        return R.fail(message);
-    }
-
-    /**
-     * 婕旂ず妯″紡寮傚父
-     */
-    @ExceptionHandler(DemoModeException.class)
-    public R<Void> handleDemoModeException(DemoModeException e) {
-        return R.fail("婕旂ず妯″紡锛屼笉鍏佽鎿嶄綔");
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java
new file mode 100644
index 0000000..6936bc3
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java
@@ -0,0 +1,59 @@
+package org.dromara.common.security.config;
+
+import cn.dev33.satoken.interceptor.SaInterceptor;
+import cn.dev33.satoken.router.SaRouter;
+import cn.dev33.satoken.stp.StpUtil;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.security.config.properties.SecurityProperties;
+import org.dromara.common.security.handler.AllUrlHandler;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * 鏉冮檺瀹夊叏閰嶇疆
+ *
+ * @author Lion Li
+ */
+
+@Slf4j
+@AutoConfiguration
+@EnableConfigurationProperties(SecurityProperties.class)
+@RequiredArgsConstructor
+public class SecurityConfig implements WebMvcConfigurer {
+
+    private final SecurityProperties securityProperties;
+
+    /**
+     * 娉ㄥ唽sa-token鐨勬嫤鎴櫒
+     */
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        // 娉ㄥ唽璺敱鎷︽埅鍣紝鑷畾涔夐獙璇佽鍒�
+        registry.addInterceptor(new SaInterceptor(handler -> {
+            AllUrlHandler allUrlHandler = SpringUtils.getBean(AllUrlHandler.class);
+            // 鐧诲綍楠岃瘉 -- 鎺掗櫎澶氫釜璺緞
+            SaRouter
+                // 鑾峰彇鎵�鏈夌殑
+                .match(allUrlHandler.getUrls())
+                // 瀵规湭鎺掗櫎鐨勮矾寰勮繘琛屾鏌�
+                .check(() -> {
+                    // 妫�鏌ユ槸鍚︾櫥褰� 鏄惁鏈塼oken
+                    StpUtil.checkLogin();
+
+                    // 鏈夋晥鐜囧奖鍝� 鐢ㄤ簬涓存椂娴嬭瘯
+                    // if (log.isDebugEnabled()) {
+                    //     log.debug("鍓╀綑鏈夋晥鏃堕棿: {}", StpUtil.getTokenTimeout());
+                    //     log.debug("涓存椂鏈夋晥鏃堕棿: {}", StpUtil.getTokenActivityTimeout());
+                    // }
+
+                });
+        })).addPathPatterns("/**")
+            // 鎺掗櫎涓嶉渶瑕佹嫤鎴殑璺緞
+            .excludePathPatterns(securityProperties.getExcludes());
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/properties/SecurityProperties.java b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/properties/SecurityProperties.java
new file mode 100644
index 0000000..be1cc6e
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/properties/SecurityProperties.java
@@ -0,0 +1,21 @@
+package org.dromara.common.security.config.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * Security 閰嶇疆灞炴��
+ *
+ * @author Lion Li
+ */
+@Data
+@ConfigurationProperties(prefix = "security")
+public class SecurityProperties {
+
+    /**
+     * 鎺掗櫎璺緞
+     */
+    private String[] excludes;
+
+
+}
diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/handler/AllUrlHandler.java b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/handler/AllUrlHandler.java
new file mode 100644
index 0000000..a0c6ada
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/handler/AllUrlHandler.java
@@ -0,0 +1,39 @@
+package org.dromara.common.security.handler;
+
+import cn.hutool.core.util.ReUtil;
+import org.dromara.common.core.utils.SpringUtils;
+import lombok.Data;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
+
+import java.util.*;
+import java.util.regex.Pattern;
+
+/**
+ * 鑾峰彇鎵�鏈塙rl閰嶇疆
+ *
+ * @author Lion Li
+ */
+@Data
+public class AllUrlHandler implements InitializingBean {
+
+    private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}");
+
+    private List<String> urls = new ArrayList<>();
+
+    @Override
+    public void afterPropertiesSet() {
+        Set<String> set = new HashSet<>();
+        RequestMappingHandlerMapping mapping = SpringUtils.getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class);
+        Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();
+        map.keySet().forEach(info -> {
+            // 鑾峰彇娉ㄨВ涓婅竟鐨� path 鏇夸唬 path variable 涓� *
+            Objects.requireNonNull(info.getPathPatternsCondition().getPatterns())
+                    .forEach(url -> set.add(ReUtil.replaceAll(url.getPatternString(), PATTERN, "*")));
+        });
+        urls.addAll(set);
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/handler/GlobalExceptionHandler.java b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/handler/GlobalExceptionHandler.java
new file mode 100644
index 0000000..ca4c3cb
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/handler/GlobalExceptionHandler.java
@@ -0,0 +1,141 @@
+package org.dromara.common.security.handler;
+
+import cn.dev33.satoken.exception.NotLoginException;
+import cn.dev33.satoken.exception.NotPermissionException;
+import cn.dev33.satoken.exception.NotRoleException;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.http.HttpStatus;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.exception.DemoModeException;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.StreamUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.support.DefaultMessageSourceResolvable;
+import org.springframework.validation.BindException;
+import org.springframework.web.HttpRequestMethodNotSupportedException;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.validation.ConstraintViolation;
+import jakarta.validation.ConstraintViolationException;
+
+/**
+ * 鍏ㄥ眬寮傚父澶勭悊鍣�
+ *
+ * @author Lion Li
+ */
+@Slf4j
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+
+    /**
+     * 鏉冮檺鐮佸紓甯�
+     */
+    @ExceptionHandler(NotPermissionException.class)
+    public R<Void> handleNotPermissionException(NotPermissionException e, HttpServletRequest request) {
+        String requestURI = request.getRequestURI();
+        log.error("璇锋眰鍦板潃'{}',鏉冮檺鐮佹牎楠屽け璐�'{}'", requestURI, e.getMessage());
+        return R.fail(HttpStatus.HTTP_FORBIDDEN, "娌℃湁璁块棶鏉冮檺锛岃鑱旂郴绠$悊鍛樻巿鏉�");
+    }
+
+    /**
+     * 瑙掕壊鏉冮檺寮傚父
+     */
+    @ExceptionHandler(NotRoleException.class)
+    public R<Void> handleNotRoleException(NotRoleException e, HttpServletRequest request) {
+        String requestURI = request.getRequestURI();
+        log.error("璇锋眰鍦板潃'{}',瑙掕壊鏉冮檺鏍¢獙澶辫触'{}'", requestURI, e.getMessage());
+        return R.fail(HttpStatus.HTTP_FORBIDDEN, "娌℃湁璁块棶鏉冮檺锛岃鑱旂郴绠$悊鍛樻巿鏉�");
+    }
+
+    /**
+     * 璁よ瘉澶辫触
+     */
+    @ExceptionHandler(NotLoginException.class)
+    public R<Void> handleNotLoginException(NotLoginException e, HttpServletRequest request) {
+        String requestURI = request.getRequestURI();
+        log.error("璇锋眰鍦板潃'{}',璁よ瘉澶辫触'{}',鏃犳硶璁块棶绯荤粺璧勬簮", requestURI, e.getMessage());
+        return R.fail(HttpStatus.HTTP_UNAUTHORIZED, "璁よ瘉澶辫触锛屾棤娉曡闂郴缁熻祫婧�");
+    }
+
+    /**
+     * 璇锋眰鏂瑰紡涓嶆敮鎸�
+     */
+    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
+    public R<Void> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,
+                                                                HttpServletRequest request) {
+        String requestURI = request.getRequestURI();
+        log.error("璇锋眰鍦板潃'{}',涓嶆敮鎸�'{}'璇锋眰", requestURI, e.getMethod());
+        return R.fail(e.getMessage());
+    }
+
+    /**
+     * 涓氬姟寮傚父
+     */
+    @ExceptionHandler(ServiceException.class)
+    public R<Void> handleServiceException(ServiceException e, HttpServletRequest request) {
+        log.error(e.getMessage(), e);
+        Integer code = e.getCode();
+        return ObjectUtil.isNotNull(code) ? R.fail(code, e.getMessage()) : R.fail(e.getMessage());
+    }
+
+    /**
+     * 鎷︽埅鏈煡鐨勮繍琛屾椂寮傚父
+     */
+    @ExceptionHandler(RuntimeException.class)
+    public R<Void> handleRuntimeException(RuntimeException e, HttpServletRequest request) {
+        String requestURI = request.getRequestURI();
+        log.error("璇锋眰鍦板潃'{}',鍙戠敓鏈煡寮傚父.", requestURI, e);
+        return R.fail(e.getMessage());
+    }
+
+    /**
+     * 绯荤粺寮傚父
+     */
+    @ExceptionHandler(Exception.class)
+    public R<Void> handleException(Exception e, HttpServletRequest request) {
+        String requestURI = request.getRequestURI();
+        log.error("璇锋眰鍦板潃'{}',鍙戠敓绯荤粺寮傚父.", requestURI, e);
+        return R.fail(e.getMessage());
+    }
+
+    /**
+     * 鑷畾涔夐獙璇佸紓甯�
+     */
+    @ExceptionHandler(BindException.class)
+    public R<Void> handleBindException(BindException e) {
+        log.error(e.getMessage(), e);
+        String message = StreamUtils.join(e.getAllErrors(), DefaultMessageSourceResolvable::getDefaultMessage, ", ");
+        return R.fail(message);
+    }
+
+    /**
+     * 鑷畾涔夐獙璇佸紓甯�
+     */
+    @ExceptionHandler(ConstraintViolationException.class)
+    public R<Void> constraintViolationException(ConstraintViolationException e) {
+        log.error(e.getMessage(), e);
+        String message = StreamUtils.join(e.getConstraintViolations(), ConstraintViolation::getMessage, ", ");
+        return R.fail(message);
+    }
+
+    /**
+     * 鑷畾涔夐獙璇佸紓甯�
+     */
+    @ExceptionHandler(MethodArgumentNotValidException.class)
+    public R<Void> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
+        log.error(e.getMessage(), e);
+        String message = e.getBindingResult().getFieldError().getDefaultMessage();
+        return R.fail(message);
+    }
+
+    /**
+     * 婕旂ず妯″紡寮傚父
+     */
+    @ExceptionHandler(DemoModeException.class)
+    public R<Void> handleDemoModeException(DemoModeException e) {
+        return R.fail("婕旂ず妯″紡锛屼笉鍏佽鎿嶄綔");
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index a72b34d..f78c781 100644
--- a/ruoyi-common/ruoyi-common-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-common/ruoyi-common-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1,3 +1,3 @@
-com.ruoyi.common.security.handler.GlobalExceptionHandler
-com.ruoyi.common.security.handler.AllUrlHandler
-com.ruoyi.common.security.config.SecurityConfig
+org.dromara.common.security.handler.GlobalExceptionHandler
+org.dromara.common.security.handler.AllUrlHandler
+org.dromara.common.security.config.SecurityConfig
diff --git a/ruoyi-common/ruoyi-common-sensitive/pom.xml b/ruoyi-common/ruoyi-common-sensitive/pom.xml
index b9b2a23..532e618 100644
--- a/ruoyi-common/ruoyi-common-sensitive/pom.xml
+++ b/ruoyi-common/ruoyi-common-sensitive/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-common</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -18,7 +18,7 @@
 
     <dependencies>
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-json</artifactId>
         </dependency>
     </dependencies>
diff --git a/ruoyi-common/ruoyi-common-sensitive/src/main/java/com/ruoyi/common/sensitive/annotation/Sensitive.java b/ruoyi-common/ruoyi-common-sensitive/src/main/java/com/ruoyi/common/sensitive/annotation/Sensitive.java
deleted file mode 100644
index 1e448e1..0000000
--- a/ruoyi-common/ruoyi-common-sensitive/src/main/java/com/ruoyi/common/sensitive/annotation/Sensitive.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.ruoyi.common.sensitive.annotation;
-
-import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
-import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-import com.ruoyi.common.sensitive.core.SensitiveStrategy;
-import com.ruoyi.common.sensitive.handler.SensitiveHandler;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * 鏁版嵁鑴辨晱娉ㄨВ
- *
- * @author zhujie
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.FIELD)
-@JacksonAnnotationsInside
-@JsonSerialize(using = SensitiveHandler.class)
-public @interface Sensitive {
-    SensitiveStrategy strategy();
-}
diff --git a/ruoyi-common/ruoyi-common-sensitive/src/main/java/com/ruoyi/common/sensitive/core/SensitiveService.java b/ruoyi-common/ruoyi-common-sensitive/src/main/java/com/ruoyi/common/sensitive/core/SensitiveService.java
deleted file mode 100644
index 49c6ae8..0000000
--- a/ruoyi-common/ruoyi-common-sensitive/src/main/java/com/ruoyi/common/sensitive/core/SensitiveService.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.ruoyi.common.sensitive.core;
-
-/**
- * 鑴辨晱鏈嶅姟
- * 榛樿绠$悊鍛樹笉杩囨护
- * 闇�鑷鏍规嵁涓氬姟閲嶅啓瀹炵幇
- *
- * @author Lion Li
- * @version 3.6.0
- */
-public interface SensitiveService {
-
-    /**
-     * 鏄惁鑴辨晱
-     */
-    boolean isSensitive();
-
-}
diff --git a/ruoyi-common/ruoyi-common-sensitive/src/main/java/com/ruoyi/common/sensitive/core/SensitiveStrategy.java b/ruoyi-common/ruoyi-common-sensitive/src/main/java/com/ruoyi/common/sensitive/core/SensitiveStrategy.java
deleted file mode 100644
index 57791db..0000000
--- a/ruoyi-common/ruoyi-common-sensitive/src/main/java/com/ruoyi/common/sensitive/core/SensitiveStrategy.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.ruoyi.common.sensitive.core;
-
-import cn.hutool.core.util.DesensitizedUtil;
-import lombok.AllArgsConstructor;
-
-import java.util.function.Function;
-
-/**
- * 鑴辨晱绛栫暐
- *
- * @author Yjoioooo
- * @version 3.6.0
- */
-@AllArgsConstructor
-public enum SensitiveStrategy {
-
-    /**
-     * 韬唤璇佽劚鏁�
-     */
-    ID_CARD(s -> DesensitizedUtil.idCardNum(s, 3, 4)),
-
-    /**
-     * 鎵嬫満鍙疯劚鏁�
-     */
-    PHONE(DesensitizedUtil::mobilePhone),
-
-    /**
-     * 鍦板潃鑴辨晱
-     */
-    ADDRESS(s -> DesensitizedUtil.address(s, 8)),
-
-    /**
-     * 閭鑴辨晱
-     */
-    EMAIL(DesensitizedUtil::email),
-
-    /**
-     * 閾惰鍗�
-     */
-    BANK_CARD(DesensitizedUtil::bankCard);
-
-    //鍙嚜琛屾坊鍔犲叾浠栬劚鏁忕瓥鐣�
-
-    private final Function<String, String> desensitizer;
-
-    public Function<String, String> desensitizer() {
-        return desensitizer;
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-sensitive/src/main/java/com/ruoyi/common/sensitive/handler/SensitiveHandler.java b/ruoyi-common/ruoyi-common-sensitive/src/main/java/com/ruoyi/common/sensitive/handler/SensitiveHandler.java
deleted file mode 100644
index 4141d3c..0000000
--- a/ruoyi-common/ruoyi-common-sensitive/src/main/java/com/ruoyi/common/sensitive/handler/SensitiveHandler.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.ruoyi.common.sensitive.handler;
-
-import cn.hutool.core.util.ObjectUtil;
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.BeanProperty;
-import com.fasterxml.jackson.databind.JsonMappingException;
-import com.fasterxml.jackson.databind.JsonSerializer;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import com.fasterxml.jackson.databind.ser.ContextualSerializer;
-import com.ruoyi.common.core.utils.SpringUtils;
-import com.ruoyi.common.sensitive.annotation.Sensitive;
-import com.ruoyi.common.sensitive.core.SensitiveService;
-import com.ruoyi.common.sensitive.core.SensitiveStrategy;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.BeansException;
-
-import java.io.IOException;
-import java.util.Objects;
-
-/**
- * 鏁版嵁鑴辨晱json搴忓垪鍖栧伐鍏�
- *
- * @author Yjoioooo
- */
-@Slf4j
-public class SensitiveHandler extends JsonSerializer<String> implements ContextualSerializer {
-
-    private SensitiveStrategy strategy;
-
-    @Override
-    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
-        try {
-            SensitiveService sensitiveService = SpringUtils.getBean(SensitiveService.class);
-            if (ObjectUtil.isNotNull(sensitiveService) && sensitiveService.isSensitive()) {
-                gen.writeString(strategy.desensitizer().apply(value));
-            } else {
-                gen.writeString(value);
-            }
-        } catch (BeansException e) {
-            log.error("鑴辨晱瀹炵幇涓嶅瓨鍦�, 閲囩敤榛樿澶勭悊 => {}", e.getMessage());
-            gen.writeString(value);
-        }
-    }
-
-    @Override
-    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
-        Sensitive annotation = property.getAnnotation(Sensitive.class);
-        if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass())) {
-            this.strategy = annotation.strategy();
-            return this;
-        }
-        return prov.findValueSerializer(property.getType(), property);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/annotation/Sensitive.java b/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/annotation/Sensitive.java
new file mode 100644
index 0000000..f2def8a
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/annotation/Sensitive.java
@@ -0,0 +1,24 @@
+package org.dromara.common.sensitive.annotation;
+
+import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import org.dromara.common.sensitive.core.SensitiveStrategy;
+import org.dromara.common.sensitive.handler.SensitiveHandler;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 鏁版嵁鑴辨晱娉ㄨВ
+ *
+ * @author zhujie
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+@JacksonAnnotationsInside
+@JsonSerialize(using = SensitiveHandler.class)
+public @interface Sensitive {
+    SensitiveStrategy strategy();
+}
diff --git a/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/core/SensitiveService.java b/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/core/SensitiveService.java
new file mode 100644
index 0000000..4b57fcb
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/core/SensitiveService.java
@@ -0,0 +1,18 @@
+package org.dromara.common.sensitive.core;
+
+/**
+ * 鑴辨晱鏈嶅姟
+ * 榛樿绠$悊鍛樹笉杩囨护
+ * 闇�鑷鏍规嵁涓氬姟閲嶅啓瀹炵幇
+ *
+ * @author Lion Li
+ * @version 3.6.0
+ */
+public interface SensitiveService {
+
+    /**
+     * 鏄惁鑴辨晱
+     */
+    boolean isSensitive();
+
+}
diff --git a/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/core/SensitiveStrategy.java b/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/core/SensitiveStrategy.java
new file mode 100644
index 0000000..9d1978a
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/core/SensitiveStrategy.java
@@ -0,0 +1,49 @@
+package org.dromara.common.sensitive.core;
+
+import cn.hutool.core.util.DesensitizedUtil;
+import lombok.AllArgsConstructor;
+
+import java.util.function.Function;
+
+/**
+ * 鑴辨晱绛栫暐
+ *
+ * @author Yjoioooo
+ * @version 3.6.0
+ */
+@AllArgsConstructor
+public enum SensitiveStrategy {
+
+    /**
+     * 韬唤璇佽劚鏁�
+     */
+    ID_CARD(s -> DesensitizedUtil.idCardNum(s, 3, 4)),
+
+    /**
+     * 鎵嬫満鍙疯劚鏁�
+     */
+    PHONE(DesensitizedUtil::mobilePhone),
+
+    /**
+     * 鍦板潃鑴辨晱
+     */
+    ADDRESS(s -> DesensitizedUtil.address(s, 8)),
+
+    /**
+     * 閭鑴辨晱
+     */
+    EMAIL(DesensitizedUtil::email),
+
+    /**
+     * 閾惰鍗�
+     */
+    BANK_CARD(DesensitizedUtil::bankCard);
+
+    //鍙嚜琛屾坊鍔犲叾浠栬劚鏁忕瓥鐣�
+
+    private final Function<String, String> desensitizer;
+
+    public Function<String, String> desensitizer() {
+        return desensitizer;
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/handler/SensitiveHandler.java b/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/handler/SensitiveHandler.java
new file mode 100644
index 0000000..3c8b78a
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/handler/SensitiveHandler.java
@@ -0,0 +1,54 @@
+package org.dromara.common.sensitive.handler;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.ContextualSerializer;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.sensitive.annotation.Sensitive;
+import org.dromara.common.sensitive.core.SensitiveService;
+import org.dromara.common.sensitive.core.SensitiveStrategy;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeansException;
+
+import java.io.IOException;
+import java.util.Objects;
+
+/**
+ * 鏁版嵁鑴辨晱json搴忓垪鍖栧伐鍏�
+ *
+ * @author Yjoioooo
+ */
+@Slf4j
+public class SensitiveHandler extends JsonSerializer<String> implements ContextualSerializer {
+
+    private SensitiveStrategy strategy;
+
+    @Override
+    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
+        try {
+            SensitiveService sensitiveService = SpringUtils.getBean(SensitiveService.class);
+            if (ObjectUtil.isNotNull(sensitiveService) && sensitiveService.isSensitive()) {
+                gen.writeString(strategy.desensitizer().apply(value));
+            } else {
+                gen.writeString(value);
+            }
+        } catch (BeansException e) {
+            log.error("鑴辨晱瀹炵幇涓嶅瓨鍦�, 閲囩敤榛樿澶勭悊 => {}", e.getMessage());
+            gen.writeString(value);
+        }
+    }
+
+    @Override
+    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
+        Sensitive annotation = property.getAnnotation(Sensitive.class);
+        if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass())) {
+            this.strategy = annotation.strategy();
+            return this;
+        }
+        return prov.findValueSerializer(property.getType(), property);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-sms/pom.xml b/ruoyi-common/ruoyi-common-sms/pom.xml
index 0bd4a0c..9dd6cba 100644
--- a/ruoyi-common/ruoyi-common-sms/pom.xml
+++ b/ruoyi-common/ruoyi-common-sms/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-common</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -18,7 +18,7 @@
 
     <dependencies>
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-json</artifactId>
         </dependency>
 
diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/config/SmsConfig.java b/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/config/SmsConfig.java
deleted file mode 100644
index ecc89af..0000000
--- a/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/config/SmsConfig.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.ruoyi.common.sms.config;
-
-import com.ruoyi.common.sms.config.properties.SmsProperties;
-import com.ruoyi.common.sms.core.AliyunSmsTemplate;
-import com.ruoyi.common.sms.core.SmsTemplate;
-import com.ruoyi.common.sms.core.TencentSmsTemplate;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * 鐭俊閰嶇疆绫�
- *
- * @author Lion Li
- * @version 4.2.0
- */
-@AutoConfiguration
-@EnableConfigurationProperties(SmsProperties.class)
-public class SmsConfig {
-
-    @Configuration
-    @ConditionalOnProperty(value = "sms.enabled", havingValue = "true")
-    @ConditionalOnClass(com.aliyun.dysmsapi20170525.Client.class)
-    static class AliyunSmsConfig {
-
-        @Bean
-        public SmsTemplate aliyunSmsTemplate(SmsProperties smsProperties) {
-            return new AliyunSmsTemplate(smsProperties);
-        }
-
-    }
-
-    @Configuration
-    @ConditionalOnProperty(value = "sms.enabled", havingValue = "true")
-    @ConditionalOnClass(com.tencentcloudapi.sms.v20190711.SmsClient.class)
-    static class TencentSmsConfig {
-
-        @Bean
-        public SmsTemplate tencentSmsTemplate(SmsProperties smsProperties) {
-            return new TencentSmsTemplate(smsProperties);
-        }
-
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/config/properties/SmsProperties.java b/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/config/properties/SmsProperties.java
deleted file mode 100644
index 57b974a..0000000
--- a/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/config/properties/SmsProperties.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.ruoyi.common.sms.config.properties;
-
-import lombok.Data;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-/**
- * SMS鐭俊 閰嶇疆灞炴��
- *
- * @author Lion Li
- * @version 4.2.0
- */
-@Data
-@ConfigurationProperties(prefix = "sms")
-public class SmsProperties {
-
-    private Boolean enabled;
-
-    /**
-     * 閰嶇疆鑺傜偣
-     * 闃块噷浜� dysmsapi.aliyuncs.com
-     * 鑵捐浜� sms.tencentcloudapi.com
-     */
-    private String endpoint;
-
-    /**
-     * key
-     */
-    private String accessKeyId;
-
-    /**
-     * 瀵嗗寵
-     */
-    private String accessKeySecret;
-
-    /*
-     * 鐭俊绛惧悕
-     */
-    private String signName;
-
-    /**
-     * 鐭俊搴旂敤ID (鑵捐涓撳睘)
-     */
-    private String sdkAppId;
-
-}
diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/core/AliyunSmsTemplate.java b/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/core/AliyunSmsTemplate.java
deleted file mode 100644
index b516afa..0000000
--- a/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/core/AliyunSmsTemplate.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package com.ruoyi.common.sms.core;
-
-import com.aliyun.dysmsapi20170525.Client;
-import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
-import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
-import com.aliyun.teaopenapi.models.Config;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.json.utils.JsonUtils;
-import com.ruoyi.common.sms.config.properties.SmsProperties;
-import com.ruoyi.common.sms.entity.SmsResult;
-import com.ruoyi.common.sms.exception.SmsException;
-import lombok.SneakyThrows;
-
-import java.util.Map;
-
-/**
- * Aliyun 鐭俊妯℃澘
- *
- * @author Lion Li
- * @version 4.2.0
- */
-public class AliyunSmsTemplate implements SmsTemplate {
-
-    private SmsProperties properties;
-
-    private Client client;
-
-    @SneakyThrows(Exception.class)
-    public AliyunSmsTemplate(SmsProperties smsProperties) {
-        this.properties = smsProperties;
-        Config config = new Config()
-            // 鎮ㄧ殑AccessKey ID
-            .setAccessKeyId(smsProperties.getAccessKeyId())
-            // 鎮ㄧ殑AccessKey Secret
-            .setAccessKeySecret(smsProperties.getAccessKeySecret())
-            // 璁块棶鐨勫煙鍚�
-            .setEndpoint(smsProperties.getEndpoint());
-        this.client = new Client(config);
-    }
-
-    @Override
-    public SmsResult send(String phones, String templateId, Map<String, String> param) {
-        if (StringUtils.isBlank(phones)) {
-            throw new SmsException("鎵嬫満鍙蜂笉鑳戒负绌�");
-        }
-        if (StringUtils.isBlank(templateId)) {
-            throw new SmsException("妯℃澘ID涓嶈兘涓虹┖");
-        }
-        SendSmsRequest req = new SendSmsRequest()
-            .setPhoneNumbers(phones)
-            .setSignName(properties.getSignName())
-            .setTemplateCode(templateId)
-            .setTemplateParam(JsonUtils.toJsonString(param));
-        try {
-            SendSmsResponse resp = client.sendSms(req);
-            return SmsResult.builder()
-                .isSuccess("OK".equals(resp.getBody().getCode()))
-                .message(resp.getBody().getMessage())
-                .response(JsonUtils.toJsonString(resp))
-                .build();
-        } catch (Exception e) {
-            throw new SmsException(e.getMessage());
-        }
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/core/SmsTemplate.java b/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/core/SmsTemplate.java
deleted file mode 100644
index eb61b86..0000000
--- a/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/core/SmsTemplate.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.ruoyi.common.sms.core;
-
-import com.ruoyi.common.sms.entity.SmsResult;
-
-import java.util.Map;
-
-/**
- * 鐭俊妯℃澘
- *
- * @author Lion Li
- * @version 4.2.0
- */
-public interface SmsTemplate {
-
-    /**
-     * 鍙戦�佺煭淇�
-     *
-     * @param phones     鐢佃瘽鍙�(澶氫釜閫楀彿鍒嗗壊)
-     * @param templateId 妯℃澘id
-     * @param param      妯℃澘瀵瑰簲鍙傛暟
-     *                   闃块噷 闇�浣跨敤 妯℃澘鍙橀噺鍚嶇О瀵瑰簲鍐呭 渚嬪: code=1234
-     *                   鑵捐 闇�浣跨敤 妯℃澘鍙橀噺椤哄簭瀵瑰簲鍐呭 渚嬪: 1=1234, 1涓烘ā鏉垮唴绗竴涓弬鏁�
-     */
-    SmsResult send(String phones, String templateId, Map<String, String> param);
-
-}
diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/core/TencentSmsTemplate.java b/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/core/TencentSmsTemplate.java
deleted file mode 100644
index 8dbd1ad..0000000
--- a/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/core/TencentSmsTemplate.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package com.ruoyi.common.sms.core;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.ArrayUtil;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.json.utils.JsonUtils;
-import com.ruoyi.common.sms.config.properties.SmsProperties;
-import com.ruoyi.common.sms.entity.SmsResult;
-import com.ruoyi.common.sms.exception.SmsException;
-import com.tencentcloudapi.common.Credential;
-import com.tencentcloudapi.common.profile.ClientProfile;
-import com.tencentcloudapi.common.profile.HttpProfile;
-import com.tencentcloudapi.sms.v20190711.SmsClient;
-import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest;
-import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse;
-import com.tencentcloudapi.sms.v20190711.models.SendStatus;
-import lombok.SneakyThrows;
-
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-/**
- * Tencent 鐭俊妯℃澘
- *
- * @author Lion Li
- * @version 4.2.0
- */
-public class TencentSmsTemplate implements SmsTemplate {
-
-    private SmsProperties properties;
-
-    private SmsClient client;
-
-    @SneakyThrows(Exception.class)
-    public TencentSmsTemplate(SmsProperties smsProperties) {
-        this.properties = smsProperties;
-        Credential credential = new Credential(smsProperties.getAccessKeyId(), smsProperties.getAccessKeySecret());
-        HttpProfile httpProfile = new HttpProfile();
-        httpProfile.setEndpoint(smsProperties.getEndpoint());
-        ClientProfile clientProfile = new ClientProfile();
-        clientProfile.setHttpProfile(httpProfile);
-        this.client = new SmsClient(credential, "", clientProfile);
-    }
-
-    @Override
-    public SmsResult send(String phones, String templateId, Map<String, String> param) {
-        if (StringUtils.isBlank(phones)) {
-            throw new SmsException("鎵嬫満鍙蜂笉鑳戒负绌�");
-        }
-        if (StringUtils.isBlank(templateId)) {
-            throw new SmsException("妯℃澘ID涓嶈兘涓虹┖");
-        }
-        SendSmsRequest req = new SendSmsRequest();
-        Set<String> set = Arrays.stream(phones.split(StringUtils.SEPARATOR)).map(p -> "+86" + p).collect(Collectors.toSet());
-        req.setPhoneNumberSet(ArrayUtil.toArray(set, String.class));
-        if (CollUtil.isNotEmpty(param)) {
-            req.setTemplateParamSet(ArrayUtil.toArray(param.values(), String.class));
-        }
-        req.setTemplateID(templateId);
-        req.setSign(properties.getSignName());
-        req.setSmsSdkAppid(properties.getSdkAppId());
-        try {
-            SendSmsResponse resp = client.SendSms(req);
-            SmsResult.SmsResultBuilder builder = SmsResult.builder()
-                .isSuccess(true)
-                .message("send success")
-                .response(JsonUtils.toJsonString(resp));
-            for (SendStatus sendStatus : resp.getSendStatusSet()) {
-                if (!"Ok".equals(sendStatus.getCode())) {
-                    builder.isSuccess(false).message(sendStatus.getMessage());
-                    break;
-                }
-            }
-            return builder.build();
-        } catch (Exception e) {
-            throw new SmsException(e.getMessage());
-        }
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/entity/SmsResult.java b/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/entity/SmsResult.java
deleted file mode 100644
index d436805..0000000
--- a/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/entity/SmsResult.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.ruoyi.common.sms.entity;
-
-import lombok.Builder;
-import lombok.Data;
-
-/**
- * 涓婁紶杩斿洖浣�
- *
- * @author Lion Li
- */
-@Data
-@Builder
-public class SmsResult {
-
-    /**
-     * 鏄惁鎴愬姛
-     */
-    private boolean isSuccess;
-
-    /**
-     * 鍝嶅簲娑堟伅
-     */
-    private String message;
-
-    /**
-     * 瀹為檯鍝嶅簲浣�
-     * <p>
-     * 鍙嚜琛岃浆鎹负 SDK 瀵瑰簲鐨� SendSmsResponse
-     */
-    private String response;
-}
diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/exception/SmsException.java b/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/exception/SmsException.java
deleted file mode 100644
index a332aee..0000000
--- a/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/exception/SmsException.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.ruoyi.common.sms.exception;
-
-import java.io.Serial;
-
-/**
- * Sms寮傚父绫�
- *
- * @author Lion Li
- */
-public class SmsException extends RuntimeException {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    public SmsException(String msg) {
-        super(msg);
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsConfig.java b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsConfig.java
new file mode 100644
index 0000000..86881f1
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsConfig.java
@@ -0,0 +1,48 @@
+package org.dromara.common.sms.config;
+
+import org.dromara.common.sms.config.properties.SmsProperties;
+import org.dromara.common.sms.core.AliyunSmsTemplate;
+import org.dromara.common.sms.core.SmsTemplate;
+import org.dromara.common.sms.core.TencentSmsTemplate;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 鐭俊閰嶇疆绫�
+ *
+ * @author Lion Li
+ * @version 4.2.0
+ */
+@AutoConfiguration
+@EnableConfigurationProperties(SmsProperties.class)
+public class SmsConfig {
+
+    @Configuration
+    @ConditionalOnProperty(value = "sms.enabled", havingValue = "true")
+    @ConditionalOnClass(com.aliyun.dysmsapi20170525.Client.class)
+    static class AliyunSmsConfig {
+
+        @Bean
+        public SmsTemplate aliyunSmsTemplate(SmsProperties smsProperties) {
+            return new AliyunSmsTemplate(smsProperties);
+        }
+
+    }
+
+    @Configuration
+    @ConditionalOnProperty(value = "sms.enabled", havingValue = "true")
+    @ConditionalOnClass(com.tencentcloudapi.sms.v20190711.SmsClient.class)
+    static class TencentSmsConfig {
+
+        @Bean
+        public SmsTemplate tencentSmsTemplate(SmsProperties smsProperties) {
+            return new TencentSmsTemplate(smsProperties);
+        }
+
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/properties/SmsProperties.java b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/properties/SmsProperties.java
new file mode 100644
index 0000000..da6d940
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/properties/SmsProperties.java
@@ -0,0 +1,45 @@
+package org.dromara.common.sms.config.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * SMS鐭俊 閰嶇疆灞炴��
+ *
+ * @author Lion Li
+ * @version 4.2.0
+ */
+@Data
+@ConfigurationProperties(prefix = "sms")
+public class SmsProperties {
+
+    private Boolean enabled;
+
+    /**
+     * 閰嶇疆鑺傜偣
+     * 闃块噷浜� dysmsapi.aliyuncs.com
+     * 鑵捐浜� sms.tencentcloudapi.com
+     */
+    private String endpoint;
+
+    /**
+     * key
+     */
+    private String accessKeyId;
+
+    /**
+     * 瀵嗗寵
+     */
+    private String accessKeySecret;
+
+    /*
+     * 鐭俊绛惧悕
+     */
+    private String signName;
+
+    /**
+     * 鐭俊搴旂敤ID (鑵捐涓撳睘)
+     */
+    private String sdkAppId;
+
+}
diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/core/AliyunSmsTemplate.java b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/core/AliyunSmsTemplate.java
new file mode 100644
index 0000000..00d8152
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/core/AliyunSmsTemplate.java
@@ -0,0 +1,66 @@
+package org.dromara.common.sms.core;
+
+import com.aliyun.dysmsapi20170525.Client;
+import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
+import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
+import com.aliyun.teaopenapi.models.Config;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.json.utils.JsonUtils;
+import org.dromara.common.sms.config.properties.SmsProperties;
+import org.dromara.common.sms.entity.SmsResult;
+import org.dromara.common.sms.exception.SmsException;
+import lombok.SneakyThrows;
+
+import java.util.Map;
+
+/**
+ * Aliyun 鐭俊妯℃澘
+ *
+ * @author Lion Li
+ * @version 4.2.0
+ */
+public class AliyunSmsTemplate implements SmsTemplate {
+
+    private SmsProperties properties;
+
+    private Client client;
+
+    @SneakyThrows(Exception.class)
+    public AliyunSmsTemplate(SmsProperties smsProperties) {
+        this.properties = smsProperties;
+        Config config = new Config()
+            // 鎮ㄧ殑AccessKey ID
+            .setAccessKeyId(smsProperties.getAccessKeyId())
+            // 鎮ㄧ殑AccessKey Secret
+            .setAccessKeySecret(smsProperties.getAccessKeySecret())
+            // 璁块棶鐨勫煙鍚�
+            .setEndpoint(smsProperties.getEndpoint());
+        this.client = new Client(config);
+    }
+
+    @Override
+    public SmsResult send(String phones, String templateId, Map<String, String> param) {
+        if (StringUtils.isBlank(phones)) {
+            throw new SmsException("鎵嬫満鍙蜂笉鑳戒负绌�");
+        }
+        if (StringUtils.isBlank(templateId)) {
+            throw new SmsException("妯℃澘ID涓嶈兘涓虹┖");
+        }
+        SendSmsRequest req = new SendSmsRequest()
+            .setPhoneNumbers(phones)
+            .setSignName(properties.getSignName())
+            .setTemplateCode(templateId)
+            .setTemplateParam(JsonUtils.toJsonString(param));
+        try {
+            SendSmsResponse resp = client.sendSms(req);
+            return SmsResult.builder()
+                .isSuccess("OK".equals(resp.getBody().getCode()))
+                .message(resp.getBody().getMessage())
+                .response(JsonUtils.toJsonString(resp))
+                .build();
+        } catch (Exception e) {
+            throw new SmsException(e.getMessage());
+        }
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/core/SmsTemplate.java b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/core/SmsTemplate.java
new file mode 100644
index 0000000..eba38df
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/core/SmsTemplate.java
@@ -0,0 +1,26 @@
+package org.dromara.common.sms.core;
+
+import org.dromara.common.sms.entity.SmsResult;
+
+import java.util.Map;
+
+/**
+ * 鐭俊妯℃澘
+ *
+ * @author Lion Li
+ * @version 4.2.0
+ */
+public interface SmsTemplate {
+
+    /**
+     * 鍙戦�佺煭淇�
+     *
+     * @param phones     鐢佃瘽鍙�(澶氫釜閫楀彿鍒嗗壊)
+     * @param templateId 妯℃澘id
+     * @param param      妯℃澘瀵瑰簲鍙傛暟
+     *                   闃块噷 闇�浣跨敤 妯℃澘鍙橀噺鍚嶇О瀵瑰簲鍐呭 渚嬪: code=1234
+     *                   鑵捐 闇�浣跨敤 妯℃澘鍙橀噺椤哄簭瀵瑰簲鍐呭 渚嬪: 1=1234, 1涓烘ā鏉垮唴绗竴涓弬鏁�
+     */
+    SmsResult send(String phones, String templateId, Map<String, String> param);
+
+}
diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/core/TencentSmsTemplate.java b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/core/TencentSmsTemplate.java
new file mode 100644
index 0000000..18d7384
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/core/TencentSmsTemplate.java
@@ -0,0 +1,82 @@
+package org.dromara.common.sms.core;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ArrayUtil;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.json.utils.JsonUtils;
+import org.dromara.common.sms.config.properties.SmsProperties;
+import org.dromara.common.sms.entity.SmsResult;
+import org.dromara.common.sms.exception.SmsException;
+import com.tencentcloudapi.common.Credential;
+import com.tencentcloudapi.common.profile.ClientProfile;
+import com.tencentcloudapi.common.profile.HttpProfile;
+import com.tencentcloudapi.sms.v20190711.SmsClient;
+import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest;
+import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse;
+import com.tencentcloudapi.sms.v20190711.models.SendStatus;
+import lombok.SneakyThrows;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Tencent 鐭俊妯℃澘
+ *
+ * @author Lion Li
+ * @version 4.2.0
+ */
+public class TencentSmsTemplate implements SmsTemplate {
+
+    private SmsProperties properties;
+
+    private SmsClient client;
+
+    @SneakyThrows(Exception.class)
+    public TencentSmsTemplate(SmsProperties smsProperties) {
+        this.properties = smsProperties;
+        Credential credential = new Credential(smsProperties.getAccessKeyId(), smsProperties.getAccessKeySecret());
+        HttpProfile httpProfile = new HttpProfile();
+        httpProfile.setEndpoint(smsProperties.getEndpoint());
+        ClientProfile clientProfile = new ClientProfile();
+        clientProfile.setHttpProfile(httpProfile);
+        this.client = new SmsClient(credential, "", clientProfile);
+    }
+
+    @Override
+    public SmsResult send(String phones, String templateId, Map<String, String> param) {
+        if (StringUtils.isBlank(phones)) {
+            throw new SmsException("鎵嬫満鍙蜂笉鑳戒负绌�");
+        }
+        if (StringUtils.isBlank(templateId)) {
+            throw new SmsException("妯℃澘ID涓嶈兘涓虹┖");
+        }
+        SendSmsRequest req = new SendSmsRequest();
+        Set<String> set = Arrays.stream(phones.split(StringUtils.SEPARATOR)).map(p -> "+86" + p).collect(Collectors.toSet());
+        req.setPhoneNumberSet(ArrayUtil.toArray(set, String.class));
+        if (CollUtil.isNotEmpty(param)) {
+            req.setTemplateParamSet(ArrayUtil.toArray(param.values(), String.class));
+        }
+        req.setTemplateID(templateId);
+        req.setSign(properties.getSignName());
+        req.setSmsSdkAppid(properties.getSdkAppId());
+        try {
+            SendSmsResponse resp = client.SendSms(req);
+            SmsResult.SmsResultBuilder builder = SmsResult.builder()
+                .isSuccess(true)
+                .message("send success")
+                .response(JsonUtils.toJsonString(resp));
+            for (SendStatus sendStatus : resp.getSendStatusSet()) {
+                if (!"Ok".equals(sendStatus.getCode())) {
+                    builder.isSuccess(false).message(sendStatus.getMessage());
+                    break;
+                }
+            }
+            return builder.build();
+        } catch (Exception e) {
+            throw new SmsException(e.getMessage());
+        }
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/entity/SmsResult.java b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/entity/SmsResult.java
new file mode 100644
index 0000000..232d612
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/entity/SmsResult.java
@@ -0,0 +1,31 @@
+package org.dromara.common.sms.entity;
+
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * 涓婁紶杩斿洖浣�
+ *
+ * @author Lion Li
+ */
+@Data
+@Builder
+public class SmsResult {
+
+    /**
+     * 鏄惁鎴愬姛
+     */
+    private boolean isSuccess;
+
+    /**
+     * 鍝嶅簲娑堟伅
+     */
+    private String message;
+
+    /**
+     * 瀹為檯鍝嶅簲浣�
+     * <p>
+     * 鍙嚜琛岃浆鎹负 SDK 瀵瑰簲鐨� SendSmsResponse
+     */
+    private String response;
+}
diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/exception/SmsException.java b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/exception/SmsException.java
new file mode 100644
index 0000000..eb7730a
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/exception/SmsException.java
@@ -0,0 +1,19 @@
+package org.dromara.common.sms.exception;
+
+import java.io.Serial;
+
+/**
+ * Sms寮傚父绫�
+ *
+ * @author Lion Li
+ */
+public class SmsException extends RuntimeException {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    public SmsException(String msg) {
+        super(msg);
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index 2eaa249..6988c7e 100644
--- a/ruoyi-common/ruoyi-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-common/ruoyi-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +1 @@
-com.ruoyi.common.sms.config.SmsConfig
+org.dromara.common.sms.config.SmsConfig
diff --git a/ruoyi-common/ruoyi-common-tenant/pom.xml b/ruoyi-common/ruoyi-common-tenant/pom.xml
index 5eeb86a..1661770 100644
--- a/ruoyi-common/ruoyi-common-tenant/pom.xml
+++ b/ruoyi-common/ruoyi-common-tenant/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-common</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -18,12 +18,12 @@
 
     <dependencies>
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-mybatis</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-redis</artifactId>
         </dependency>
 
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/config/TenantConfig.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/config/TenantConfig.java
deleted file mode 100644
index 373e77c..0000000
--- a/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/config/TenantConfig.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package com.ruoyi.common.tenant.config;
-
-import cn.dev33.satoken.dao.SaTokenDao;
-import cn.hutool.core.util.ObjectUtil;
-import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
-import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
-import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
-import com.ruoyi.common.core.utils.reflect.ReflectUtils;
-import com.ruoyi.common.mybatis.config.MybatisPlusConfig;
-import com.ruoyi.common.redis.config.RedisConfig;
-import com.ruoyi.common.redis.config.properties.RedissonProperties;
-import com.ruoyi.common.tenant.core.TenantSaTokenDao;
-import com.ruoyi.common.tenant.handle.PlusTenantLineHandler;
-import com.ruoyi.common.tenant.handle.TenantKeyPrefixHandler;
-import com.ruoyi.common.tenant.manager.TenantSpringCacheManager;
-import com.ruoyi.common.tenant.properties.TenantProperties;
-import org.redisson.config.ClusterServersConfig;
-import org.redisson.config.SingleServerConfig;
-import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.cache.CacheManager;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Primary;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * 绉熸埛閰嶇疆绫�
- *
- * @author Lion Li
- */
-@EnableConfigurationProperties(TenantProperties.class)
-@AutoConfiguration(after = {RedisConfig.class, MybatisPlusConfig.class})
-@ConditionalOnProperty(value = "tenant.enable", havingValue = "true")
-public class TenantConfig {
-
-    /**
-     * 鍒濆鍖栫鎴烽厤缃�
-     */
-    @Bean
-    public boolean tenantInit(MybatisPlusInterceptor mybatisPlusInterceptor,
-                              TenantProperties tenantProperties) {
-        List<InnerInterceptor> interceptors = new ArrayList<>();
-        // 澶氱鎴锋彃浠� 蹇呴』鏀惧埌绗竴浣�
-        interceptors.add(tenantLineInnerInterceptor(tenantProperties));
-        interceptors.addAll(mybatisPlusInterceptor.getInterceptors());
-        mybatisPlusInterceptor.setInterceptors(interceptors);
-        return true;
-    }
-
-    /**
-     * 澶氱鎴锋彃浠�
-     */
-    public TenantLineInnerInterceptor tenantLineInnerInterceptor(TenantProperties tenantProperties) {
-        return new TenantLineInnerInterceptor(new PlusTenantLineHandler(tenantProperties));
-    }
-
-    @Bean
-    public RedissonAutoConfigurationCustomizer tenantRedissonCustomizer(RedissonProperties redissonProperties) {
-        return config -> {
-            TenantKeyPrefixHandler nameMapper = new TenantKeyPrefixHandler(redissonProperties.getKeyPrefix());
-            SingleServerConfig singleServerConfig = ReflectUtils.invokeGetter(config, "singleServerConfig");
-            if (ObjectUtil.isNotNull(singleServerConfig)) {
-                // 浣跨敤鍗曟満妯″紡
-                // 璁剧疆澶氱鎴� redis key鍓嶇紑
-                singleServerConfig.setNameMapper(nameMapper);
-                ReflectUtils.invokeSetter(config, "singleServerConfig", singleServerConfig);
-            }
-            ClusterServersConfig clusterServersConfig = ReflectUtils.invokeGetter(config, "clusterServersConfig");
-            // 闆嗙兢閰嶇疆鏂瑰紡 鍙傝�冧笅鏂规敞閲�
-            if (ObjectUtil.isNotNull(clusterServersConfig)) {
-                // 璁剧疆澶氱鎴� redis key鍓嶇紑
-                clusterServersConfig.setNameMapper(nameMapper);
-                ReflectUtils.invokeSetter(config, "clusterServersConfig", clusterServersConfig);
-            }
-        };
-    }
-
-    /**
-     * 澶氱鎴风紦瀛樼鐞嗗櫒
-     */
-    @Primary
-    @Bean
-    public CacheManager tenantCacheManager() {
-        return new TenantSpringCacheManager();
-    }
-
-    /**
-     * 澶氱鎴烽壌鏉僤ao瀹炵幇
-     */
-    @Primary
-    @Bean
-    public SaTokenDao tenantSaTokenDao() {
-        return new TenantSaTokenDao();
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/core/TenantEntity.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/core/TenantEntity.java
deleted file mode 100644
index 2864ccd..0000000
--- a/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/core/TenantEntity.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.ruoyi.common.tenant.core;
-
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * 绉熸埛鍩虹被
- *
- * @author Michelle.Chung
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-public class TenantEntity extends BaseEntity {
-
-    /**
-     * 绉熸埛缂栧彿
-     */
-    private String tenantId;
-
-}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/core/TenantSaTokenDao.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/core/TenantSaTokenDao.java
deleted file mode 100644
index a84bbbd..0000000
--- a/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/core/TenantSaTokenDao.java
+++ /dev/null
@@ -1,148 +0,0 @@
-package com.ruoyi.common.tenant.core;
-
-import com.ruoyi.common.core.constant.GlobalConstants;
-import com.ruoyi.common.redis.utils.RedisUtils;
-import com.ruoyi.common.satoken.core.dao.PlusSaTokenDao;
-
-import java.time.Duration;
-import java.util.List;
-
-/**
- * SaToken 璁よ瘉鏁版嵁鎸佷箙灞� 閫傞厤澶氱鎴�
- *
- * @author Lion Li
- */
-public class TenantSaTokenDao extends PlusSaTokenDao {
-
-    @Override
-    public String get(String key) {
-        return super.get(GlobalConstants.GLOBAL_REDIS_KEY + key);
-    }
-
-    @Override
-    public void set(String key, String value, long timeout) {
-        super.set(GlobalConstants.GLOBAL_REDIS_KEY + key, value, timeout);
-    }
-
-    /**
-     * 淇慨鏀规寚瀹歬ey-value閿�煎 (杩囨湡鏃堕棿涓嶅彉)
-     */
-    @Override
-    public void update(String key, String value) {
-        long expire = getTimeout(key);
-        // -2 = 鏃犳閿�
-        if (expire == NOT_VALUE_EXPIRE) {
-            return;
-        }
-        this.set(key, value, expire);
-    }
-
-    /**
-     * 鍒犻櫎Value
-     */
-    @Override
-    public void delete(String key) {
-        super.delete(GlobalConstants.GLOBAL_REDIS_KEY + key);
-    }
-
-    /**
-     * 鑾峰彇Value鐨勫墿浣欏瓨娲绘椂闂� (鍗曚綅: 绉�)
-     */
-    @Override
-    public long getTimeout(String key) {
-        return super.getTimeout(GlobalConstants.GLOBAL_REDIS_KEY + key);
-    }
-
-    /**
-     * 淇敼Value鐨勫墿浣欏瓨娲绘椂闂� (鍗曚綅: 绉�)
-     */
-    @Override
-    public void updateTimeout(String key, long timeout) {
-        // 鍒ゆ柇鏄惁鎯宠璁剧疆涓烘案涔�
-        if (timeout == NEVER_EXPIRE) {
-            long expire = getTimeout(key);
-            if (expire == NEVER_EXPIRE) {
-                // 濡傛灉鍏跺凡缁忚璁剧疆涓烘案涔咃紝鍒欎笉浣滀换浣曞鐞�
-            } else {
-                // 濡傛灉灏氭湭琚缃负姘镐箙锛岄偅涔堝啀娆et涓�娆�
-                this.set(key, this.get(key), timeout);
-            }
-            return;
-        }
-        RedisUtils.expire(GlobalConstants.GLOBAL_REDIS_KEY + key, Duration.ofSeconds(timeout));
-    }
-
-
-    /**
-     * 鑾峰彇Object锛屽鏃犺繑绌�
-     */
-    @Override
-    public Object getObject(String key) {
-        return super.getObject(GlobalConstants.GLOBAL_REDIS_KEY + key);
-    }
-
-    /**
-     * 鍐欏叆Object锛屽苟璁惧畾瀛樻椿鏃堕棿 (鍗曚綅: 绉�)
-     */
-    @Override
-    public void setObject(String key, Object object, long timeout) {
-        super.setObject(GlobalConstants.GLOBAL_REDIS_KEY + key, object, timeout);
-    }
-
-    /**
-     * 鏇存柊Object (杩囨湡鏃堕棿涓嶅彉)
-     */
-    @Override
-    public void updateObject(String key, Object object) {
-        long expire = getObjectTimeout(key);
-        // -2 = 鏃犳閿�
-        if (expire == NOT_VALUE_EXPIRE) {
-            return;
-        }
-        this.setObject(key, object, expire);
-    }
-
-    /**
-     * 鍒犻櫎Object
-     */
-    @Override
-    public void deleteObject(String key) {
-        super.deleteObject(GlobalConstants.GLOBAL_REDIS_KEY + key);
-    }
-
-    /**
-     * 鑾峰彇Object鐨勫墿浣欏瓨娲绘椂闂� (鍗曚綅: 绉�)
-     */
-    @Override
-    public long getObjectTimeout(String key) {
-        return super.getObjectTimeout(GlobalConstants.GLOBAL_REDIS_KEY + key);
-    }
-
-    /**
-     * 淇敼Object鐨勫墿浣欏瓨娲绘椂闂� (鍗曚綅: 绉�)
-     */
-    @Override
-    public void updateObjectTimeout(String key, long timeout) {
-        // 鍒ゆ柇鏄惁鎯宠璁剧疆涓烘案涔�
-        if (timeout == NEVER_EXPIRE) {
-            long expire = getObjectTimeout(key);
-            if (expire == NEVER_EXPIRE) {
-                // 濡傛灉鍏跺凡缁忚璁剧疆涓烘案涔咃紝鍒欎笉浣滀换浣曞鐞�
-            } else {
-                // 濡傛灉灏氭湭琚缃负姘镐箙锛岄偅涔堝啀娆et涓�娆�
-                this.setObject(key, this.getObject(key), timeout);
-            }
-            return;
-        }
-        RedisUtils.expire(GlobalConstants.GLOBAL_REDIS_KEY + key, Duration.ofSeconds(timeout));
-    }
-
-
-    /**
-     * 鎼滅储鏁版嵁
-     */
-    @Override
-    public List<String> searchData(String prefix, String keyword, int start, int size, boolean sortType) {
-        return super.searchData(GlobalConstants.GLOBAL_REDIS_KEY + prefix, keyword, start, size, sortType);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/exception/TenantException.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/exception/TenantException.java
deleted file mode 100644
index 371bc12..0000000
--- a/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/exception/TenantException.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.ruoyi.common.tenant.exception;
-
-import com.ruoyi.common.core.exception.base.BaseException;
-
-import java.io.Serial;
-
-/**
- * 绉熸埛寮傚父绫�
- *
- * @author Lion Li
- */
-public class TenantException extends BaseException {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    public TenantException(String code, Object... args) {
-        super("tenant", code, args, null);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/handle/PlusTenantLineHandler.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/handle/PlusTenantLineHandler.java
deleted file mode 100644
index ad67ed1..0000000
--- a/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/handle/PlusTenantLineHandler.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package com.ruoyi.common.tenant.handle;
-
-import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.satoken.utils.LoginHelper;
-import com.ruoyi.common.tenant.helper.TenantHelper;
-import com.ruoyi.common.tenant.properties.TenantProperties;
-import lombok.AllArgsConstructor;
-import net.sf.jsqlparser.expression.Expression;
-import net.sf.jsqlparser.expression.NullValue;
-import net.sf.jsqlparser.expression.StringValue;
-
-import java.util.List;
-
-/**
- * 鑷畾涔夌鎴峰鐞嗗櫒
- *
- * @author Lion Li
- */
-@AllArgsConstructor
-public class PlusTenantLineHandler implements TenantLineHandler {
-
-    private final TenantProperties tenantProperties;
-
-    @Override
-    public Expression getTenantId() {
-        String tenantId = LoginHelper.getTenantId();
-        if (StringUtils.isBlank(tenantId)) {
-            return new NullValue();
-        }
-        String dynamicTenantId = TenantHelper.getDynamic();
-        if (StringUtils.isNotBlank(dynamicTenantId)) {
-            // 杩斿洖鍔ㄦ�佺鎴�
-            return new StringValue(dynamicTenantId);
-        }
-        // 杩斿洖鍥哄畾绉熸埛
-        return new StringValue(tenantId);
-    }
-
-    @Override
-    public boolean ignoreTable(String tableName) {
-        String tenantId = LoginHelper.getTenantId();
-        // 鍒ゆ柇鏄惁鏈夌鎴�
-        if (StringUtils.isNotBlank(tenantId)) {
-            // 涓嶉渶瑕佽繃婊ょ鎴风殑琛�
-            List<String> excludes = tenantProperties.getExcludes();
-            // 闈炰笟鍔¤〃
-            excludes.addAll(List.of(
-                    "gen_table",
-                    "gen_table_column"
-            ));
-            return excludes.contains(tableName);
-        }
-        return true;
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/handle/TenantKeyPrefixHandler.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/handle/TenantKeyPrefixHandler.java
deleted file mode 100644
index 729702d..0000000
--- a/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/handle/TenantKeyPrefixHandler.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package com.ruoyi.common.tenant.handle;
-
-import com.ruoyi.common.core.constant.GlobalConstants;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.redis.handler.KeyPrefixHandler;
-import com.ruoyi.common.tenant.helper.TenantHelper;
-
-/**
- * 澶氱鎴穜edis缂撳瓨key鍓嶇紑澶勭悊
- *
- * @author Lion Li
- */
-public class TenantKeyPrefixHandler extends KeyPrefixHandler {
-
-    public TenantKeyPrefixHandler(String keyPrefix) {
-        super(keyPrefix);
-    }
-
-    /**
-     * 澧炲姞鍓嶇紑
-     */
-    @Override
-    public String map(String name) {
-        if (StringUtils.isBlank(name)) {
-            return null;
-        }
-        if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
-            return super.map(name);
-        }
-        String tenantId = TenantHelper.getTenantId();
-        if (StringUtils.startsWith(name, tenantId)) {
-            // 濡傛灉瀛樺湪鍒欑洿鎺ヨ繑鍥�
-            return super.map(name);
-        }
-        return super.map(tenantId + ":" + name);
-    }
-
-    /**
-     * 鍘婚櫎鍓嶇紑
-     */
-    @Override
-    public String unmap(String name) {
-        String unmap = super.unmap(name);
-        if (StringUtils.isBlank(unmap)) {
-            return null;
-        }
-        if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
-            return super.unmap(name);
-        }
-        String tenantId = TenantHelper.getTenantId();
-        if (StringUtils.startsWith(unmap, tenantId)) {
-            // 濡傛灉瀛樺湪鍒欏垹闄�
-            return unmap.substring((tenantId + ":").length());
-        }
-        return unmap;
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/helper/TenantHelper.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/helper/TenantHelper.java
deleted file mode 100644
index 7f762aa..0000000
--- a/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/helper/TenantHelper.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package com.ruoyi.common.tenant.helper;
-
-import cn.dev33.satoken.context.SaHolder;
-import cn.dev33.satoken.spring.SpringMVCUtil;
-import cn.hutool.core.convert.Convert;
-import com.alibaba.ttl.TransmittableThreadLocal;
-import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy;
-import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
-import com.ruoyi.common.core.constant.GlobalConstants;
-import com.ruoyi.common.core.utils.SpringUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.redis.utils.RedisUtils;
-import com.ruoyi.common.satoken.utils.LoginHelper;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-
-/**
- * 绉熸埛鍔╂墜
- *
- * @author Lion Li
- */
-@Slf4j
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class TenantHelper {
-
-    private static final String DYNAMIC_TENANT_KEY = GlobalConstants.GLOBAL_REDIS_KEY + "dynamicTenant";
-
-    private static final ThreadLocal<String> TEMP_DYNAMIC_TENANT = new TransmittableThreadLocal<>();
-
-    /**
-     * 绉熸埛鍔熻兘鏄惁鍚敤
-     */
-    public static boolean isEnable() {
-        return Convert.toBool(SpringUtils.getProperty("tenant.enable"), false);
-    }
-
-    /**
-     * 寮�鍚拷鐣ョ鎴�(寮�鍚悗闇�鎵嬪姩璋冪敤 {@link #disableIgnore()} 鍏抽棴)
-     */
-    public static void enableIgnore() {
-        InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().tenantLine(true).build());
-    }
-
-    /**
-     * 鍏抽棴蹇界暐绉熸埛
-     */
-    public static void disableIgnore() {
-        InterceptorIgnoreHelper.clearIgnoreStrategy();
-    }
-
-    /**
-     * 璁剧疆鍔ㄦ�佺鎴�(涓�鐩存湁鏁� 闇�瑕佹墜鍔ㄦ竻鐞�)
-     * <p>
-     * 濡傛灉涓洪潪web鐜 閭d箞鍙湪褰撳墠绾跨▼鍐呯敓鏁�
-     */
-    public static void setDynamic(String tenantId) {
-        if (!SpringMVCUtil.isWeb()) {
-            TEMP_DYNAMIC_TENANT.set(tenantId);
-            return;
-        }
-        String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId();
-        RedisUtils.setCacheObject(cacheKey, tenantId);
-        SaHolder.getStorage().set(cacheKey, tenantId);
-    }
-
-    /**
-     * 鑾峰彇鍔ㄦ�佺鎴�(涓�鐩存湁鏁� 闇�瑕佹墜鍔ㄦ竻鐞�)
-     * <p>
-     * 濡傛灉涓洪潪web鐜 閭d箞鍙湪褰撳墠绾跨▼鍐呯敓鏁�
-     */
-    public static String getDynamic() {
-        if (!SpringMVCUtil.isWeb()) {
-            return TEMP_DYNAMIC_TENANT.get();
-        }
-        String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId();
-        String tenantId = (String) SaHolder.getStorage().get(cacheKey);
-        if (StringUtils.isNotBlank(tenantId)) {
-            return tenantId;
-        }
-        tenantId = RedisUtils.getCacheObject(cacheKey);
-        SaHolder.getStorage().set(cacheKey, tenantId);
-        return tenantId;
-    }
-
-    /**
-     * 娓呴櫎鍔ㄦ�佺鎴�
-     */
-    public static void clearDynamic() {
-        if (!SpringMVCUtil.isWeb()) {
-            TEMP_DYNAMIC_TENANT.remove();
-            return;
-        }
-        String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId();
-        RedisUtils.deleteObject(cacheKey);
-        SaHolder.getStorage().delete(cacheKey);
-    }
-
-    /**
-     * 鑾峰彇褰撳墠绉熸埛id(鍔ㄦ�佺鎴蜂紭鍏�)
-     */
-    public static String getTenantId() {
-        String tenantId = TenantHelper.getDynamic();
-        if (StringUtils.isBlank(tenantId)) {
-            tenantId = LoginHelper.getTenantId();
-        }
-        return tenantId;
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/manager/TenantSpringCacheManager.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/manager/TenantSpringCacheManager.java
deleted file mode 100644
index 83402b7..0000000
--- a/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/manager/TenantSpringCacheManager.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.ruoyi.common.tenant.manager;
-
-import com.ruoyi.common.core.constant.GlobalConstants;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.redis.manager.PlusSpringCacheManager;
-import com.ruoyi.common.tenant.helper.TenantHelper;
-import org.springframework.cache.Cache;
-
-/**
- * 閲嶅啓 cacheName 澶勭悊鏂规硶 鏀寔澶氱鎴�
- *
- * @author Lion Li
- */
-public class TenantSpringCacheManager extends PlusSpringCacheManager {
-
-    public TenantSpringCacheManager() {
-    }
-
-    @Override
-    public Cache getCache(String name) {
-        if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
-            return super.getCache(name);
-        }
-        String tenantId = TenantHelper.getTenantId();
-        if (StringUtils.startsWith(name, tenantId)) {
-            // 濡傛灉瀛樺湪鍒欑洿鎺ヨ繑鍥�
-            return super.getCache(name);
-        }
-        return super.getCache(tenantId + ":" + name);
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/properties/TenantProperties.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/properties/TenantProperties.java
deleted file mode 100644
index 473ea77..0000000
--- a/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/properties/TenantProperties.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.ruoyi.common.tenant.properties;
-
-import lombok.Data;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-import java.util.List;
-
-/**
- * 绉熸埛 閰嶇疆灞炴��
- *
- * @author Lion Li
- */
-@Data
-@ConfigurationProperties(prefix = "tenant")
-public class TenantProperties {
-
-    /**
-     * 鏄惁鍚敤
-     */
-    private Boolean enable;
-
-    /**
-     * 鎺掗櫎琛�
-     */
-    private List<String> excludes;
-
-}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/config/TenantConfig.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/config/TenantConfig.java
new file mode 100644
index 0000000..8610641
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/config/TenantConfig.java
@@ -0,0 +1,100 @@
+package org.dromara.common.tenant.config;
+
+import cn.dev33.satoken.dao.SaTokenDao;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
+import org.dromara.common.core.utils.reflect.ReflectUtils;
+import org.dromara.common.mybatis.config.MybatisPlusConfig;
+import org.dromara.common.redis.config.RedisConfig;
+import org.dromara.common.redis.config.properties.RedissonProperties;
+import org.dromara.common.tenant.core.TenantSaTokenDao;
+import org.dromara.common.tenant.handle.PlusTenantLineHandler;
+import org.dromara.common.tenant.handle.TenantKeyPrefixHandler;
+import org.dromara.common.tenant.manager.TenantSpringCacheManager;
+import org.dromara.common.tenant.properties.TenantProperties;
+import org.redisson.config.ClusterServersConfig;
+import org.redisson.config.SingleServerConfig;
+import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cache.CacheManager;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Primary;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 绉熸埛閰嶇疆绫�
+ *
+ * @author Lion Li
+ */
+@EnableConfigurationProperties(TenantProperties.class)
+@AutoConfiguration(after = {RedisConfig.class, MybatisPlusConfig.class})
+@ConditionalOnProperty(value = "tenant.enable", havingValue = "true")
+public class TenantConfig {
+
+    /**
+     * 鍒濆鍖栫鎴烽厤缃�
+     */
+    @Bean
+    public boolean tenantInit(MybatisPlusInterceptor mybatisPlusInterceptor,
+                              TenantProperties tenantProperties) {
+        List<InnerInterceptor> interceptors = new ArrayList<>();
+        // 澶氱鎴锋彃浠� 蹇呴』鏀惧埌绗竴浣�
+        interceptors.add(tenantLineInnerInterceptor(tenantProperties));
+        interceptors.addAll(mybatisPlusInterceptor.getInterceptors());
+        mybatisPlusInterceptor.setInterceptors(interceptors);
+        return true;
+    }
+
+    /**
+     * 澶氱鎴锋彃浠�
+     */
+    public TenantLineInnerInterceptor tenantLineInnerInterceptor(TenantProperties tenantProperties) {
+        return new TenantLineInnerInterceptor(new PlusTenantLineHandler(tenantProperties));
+    }
+
+    @Bean
+    public RedissonAutoConfigurationCustomizer tenantRedissonCustomizer(RedissonProperties redissonProperties) {
+        return config -> {
+            TenantKeyPrefixHandler nameMapper = new TenantKeyPrefixHandler(redissonProperties.getKeyPrefix());
+            SingleServerConfig singleServerConfig = ReflectUtils.invokeGetter(config, "singleServerConfig");
+            if (ObjectUtil.isNotNull(singleServerConfig)) {
+                // 浣跨敤鍗曟満妯″紡
+                // 璁剧疆澶氱鎴� redis key鍓嶇紑
+                singleServerConfig.setNameMapper(nameMapper);
+                ReflectUtils.invokeSetter(config, "singleServerConfig", singleServerConfig);
+            }
+            ClusterServersConfig clusterServersConfig = ReflectUtils.invokeGetter(config, "clusterServersConfig");
+            // 闆嗙兢閰嶇疆鏂瑰紡 鍙傝�冧笅鏂规敞閲�
+            if (ObjectUtil.isNotNull(clusterServersConfig)) {
+                // 璁剧疆澶氱鎴� redis key鍓嶇紑
+                clusterServersConfig.setNameMapper(nameMapper);
+                ReflectUtils.invokeSetter(config, "clusterServersConfig", clusterServersConfig);
+            }
+        };
+    }
+
+    /**
+     * 澶氱鎴风紦瀛樼鐞嗗櫒
+     */
+    @Primary
+    @Bean
+    public CacheManager tenantCacheManager() {
+        return new TenantSpringCacheManager();
+    }
+
+    /**
+     * 澶氱鎴烽壌鏉僤ao瀹炵幇
+     */
+    @Primary
+    @Bean
+    public SaTokenDao tenantSaTokenDao() {
+        return new TenantSaTokenDao();
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/core/TenantEntity.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/core/TenantEntity.java
new file mode 100644
index 0000000..8ad0d2c
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/core/TenantEntity.java
@@ -0,0 +1,21 @@
+package org.dromara.common.tenant.core;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 绉熸埛鍩虹被
+ *
+ * @author Michelle.Chung
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class TenantEntity extends BaseEntity {
+
+    /**
+     * 绉熸埛缂栧彿
+     */
+    private String tenantId;
+
+}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/core/TenantSaTokenDao.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/core/TenantSaTokenDao.java
new file mode 100644
index 0000000..b8da28e
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/core/TenantSaTokenDao.java
@@ -0,0 +1,148 @@
+package org.dromara.common.tenant.core;
+
+import org.dromara.common.core.constant.GlobalConstants;
+import org.dromara.common.redis.utils.RedisUtils;
+import org.dromara.common.satoken.core.dao.PlusSaTokenDao;
+
+import java.time.Duration;
+import java.util.List;
+
+/**
+ * SaToken 璁よ瘉鏁版嵁鎸佷箙灞� 閫傞厤澶氱鎴�
+ *
+ * @author Lion Li
+ */
+public class TenantSaTokenDao extends PlusSaTokenDao {
+
+    @Override
+    public String get(String key) {
+        return super.get(GlobalConstants.GLOBAL_REDIS_KEY + key);
+    }
+
+    @Override
+    public void set(String key, String value, long timeout) {
+        super.set(GlobalConstants.GLOBAL_REDIS_KEY + key, value, timeout);
+    }
+
+    /**
+     * 淇慨鏀规寚瀹歬ey-value閿�煎 (杩囨湡鏃堕棿涓嶅彉)
+     */
+    @Override
+    public void update(String key, String value) {
+        long expire = getTimeout(key);
+        // -2 = 鏃犳閿�
+        if (expire == NOT_VALUE_EXPIRE) {
+            return;
+        }
+        this.set(key, value, expire);
+    }
+
+    /**
+     * 鍒犻櫎Value
+     */
+    @Override
+    public void delete(String key) {
+        super.delete(GlobalConstants.GLOBAL_REDIS_KEY + key);
+    }
+
+    /**
+     * 鑾峰彇Value鐨勫墿浣欏瓨娲绘椂闂� (鍗曚綅: 绉�)
+     */
+    @Override
+    public long getTimeout(String key) {
+        return super.getTimeout(GlobalConstants.GLOBAL_REDIS_KEY + key);
+    }
+
+    /**
+     * 淇敼Value鐨勫墿浣欏瓨娲绘椂闂� (鍗曚綅: 绉�)
+     */
+    @Override
+    public void updateTimeout(String key, long timeout) {
+        // 鍒ゆ柇鏄惁鎯宠璁剧疆涓烘案涔�
+        if (timeout == NEVER_EXPIRE) {
+            long expire = getTimeout(key);
+            if (expire == NEVER_EXPIRE) {
+                // 濡傛灉鍏跺凡缁忚璁剧疆涓烘案涔咃紝鍒欎笉浣滀换浣曞鐞�
+            } else {
+                // 濡傛灉灏氭湭琚缃负姘镐箙锛岄偅涔堝啀娆et涓�娆�
+                this.set(key, this.get(key), timeout);
+            }
+            return;
+        }
+        RedisUtils.expire(GlobalConstants.GLOBAL_REDIS_KEY + key, Duration.ofSeconds(timeout));
+    }
+
+
+    /**
+     * 鑾峰彇Object锛屽鏃犺繑绌�
+     */
+    @Override
+    public Object getObject(String key) {
+        return super.getObject(GlobalConstants.GLOBAL_REDIS_KEY + key);
+    }
+
+    /**
+     * 鍐欏叆Object锛屽苟璁惧畾瀛樻椿鏃堕棿 (鍗曚綅: 绉�)
+     */
+    @Override
+    public void setObject(String key, Object object, long timeout) {
+        super.setObject(GlobalConstants.GLOBAL_REDIS_KEY + key, object, timeout);
+    }
+
+    /**
+     * 鏇存柊Object (杩囨湡鏃堕棿涓嶅彉)
+     */
+    @Override
+    public void updateObject(String key, Object object) {
+        long expire = getObjectTimeout(key);
+        // -2 = 鏃犳閿�
+        if (expire == NOT_VALUE_EXPIRE) {
+            return;
+        }
+        this.setObject(key, object, expire);
+    }
+
+    /**
+     * 鍒犻櫎Object
+     */
+    @Override
+    public void deleteObject(String key) {
+        super.deleteObject(GlobalConstants.GLOBAL_REDIS_KEY + key);
+    }
+
+    /**
+     * 鑾峰彇Object鐨勫墿浣欏瓨娲绘椂闂� (鍗曚綅: 绉�)
+     */
+    @Override
+    public long getObjectTimeout(String key) {
+        return super.getObjectTimeout(GlobalConstants.GLOBAL_REDIS_KEY + key);
+    }
+
+    /**
+     * 淇敼Object鐨勫墿浣欏瓨娲绘椂闂� (鍗曚綅: 绉�)
+     */
+    @Override
+    public void updateObjectTimeout(String key, long timeout) {
+        // 鍒ゆ柇鏄惁鎯宠璁剧疆涓烘案涔�
+        if (timeout == NEVER_EXPIRE) {
+            long expire = getObjectTimeout(key);
+            if (expire == NEVER_EXPIRE) {
+                // 濡傛灉鍏跺凡缁忚璁剧疆涓烘案涔咃紝鍒欎笉浣滀换浣曞鐞�
+            } else {
+                // 濡傛灉灏氭湭琚缃负姘镐箙锛岄偅涔堝啀娆et涓�娆�
+                this.setObject(key, this.getObject(key), timeout);
+            }
+            return;
+        }
+        RedisUtils.expire(GlobalConstants.GLOBAL_REDIS_KEY + key, Duration.ofSeconds(timeout));
+    }
+
+
+    /**
+     * 鎼滅储鏁版嵁
+     */
+    @Override
+    public List<String> searchData(String prefix, String keyword, int start, int size, boolean sortType) {
+        return super.searchData(GlobalConstants.GLOBAL_REDIS_KEY + prefix, keyword, start, size, sortType);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/exception/TenantException.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/exception/TenantException.java
new file mode 100644
index 0000000..ee2bc97
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/exception/TenantException.java
@@ -0,0 +1,20 @@
+package org.dromara.common.tenant.exception;
+
+import org.dromara.common.core.exception.base.BaseException;
+
+import java.io.Serial;
+
+/**
+ * 绉熸埛寮傚父绫�
+ *
+ * @author Lion Li
+ */
+public class TenantException extends BaseException {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    public TenantException(String code, Object... args) {
+        super("tenant", code, args, null);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/handle/PlusTenantLineHandler.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/handle/PlusTenantLineHandler.java
new file mode 100644
index 0000000..c8bb25d
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/handle/PlusTenantLineHandler.java
@@ -0,0 +1,57 @@
+package org.dromara.common.tenant.handle;
+
+import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.common.tenant.helper.TenantHelper;
+import org.dromara.common.tenant.properties.TenantProperties;
+import lombok.AllArgsConstructor;
+import net.sf.jsqlparser.expression.Expression;
+import net.sf.jsqlparser.expression.NullValue;
+import net.sf.jsqlparser.expression.StringValue;
+
+import java.util.List;
+
+/**
+ * 鑷畾涔夌鎴峰鐞嗗櫒
+ *
+ * @author Lion Li
+ */
+@AllArgsConstructor
+public class PlusTenantLineHandler implements TenantLineHandler {
+
+    private final TenantProperties tenantProperties;
+
+    @Override
+    public Expression getTenantId() {
+        String tenantId = LoginHelper.getTenantId();
+        if (StringUtils.isBlank(tenantId)) {
+            return new NullValue();
+        }
+        String dynamicTenantId = TenantHelper.getDynamic();
+        if (StringUtils.isNotBlank(dynamicTenantId)) {
+            // 杩斿洖鍔ㄦ�佺鎴�
+            return new StringValue(dynamicTenantId);
+        }
+        // 杩斿洖鍥哄畾绉熸埛
+        return new StringValue(tenantId);
+    }
+
+    @Override
+    public boolean ignoreTable(String tableName) {
+        String tenantId = LoginHelper.getTenantId();
+        // 鍒ゆ柇鏄惁鏈夌鎴�
+        if (StringUtils.isNotBlank(tenantId)) {
+            // 涓嶉渶瑕佽繃婊ょ鎴风殑琛�
+            List<String> excludes = tenantProperties.getExcludes();
+            // 闈炰笟鍔¤〃
+            excludes.addAll(List.of(
+                    "gen_table",
+                    "gen_table_column"
+            ));
+            return excludes.contains(tableName);
+        }
+        return true;
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/handle/TenantKeyPrefixHandler.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/handle/TenantKeyPrefixHandler.java
new file mode 100644
index 0000000..c9c2f95
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/handle/TenantKeyPrefixHandler.java
@@ -0,0 +1,58 @@
+package org.dromara.common.tenant.handle;
+
+import org.dromara.common.core.constant.GlobalConstants;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.redis.handler.KeyPrefixHandler;
+import org.dromara.common.tenant.helper.TenantHelper;
+
+/**
+ * 澶氱鎴穜edis缂撳瓨key鍓嶇紑澶勭悊
+ *
+ * @author Lion Li
+ */
+public class TenantKeyPrefixHandler extends KeyPrefixHandler {
+
+    public TenantKeyPrefixHandler(String keyPrefix) {
+        super(keyPrefix);
+    }
+
+    /**
+     * 澧炲姞鍓嶇紑
+     */
+    @Override
+    public String map(String name) {
+        if (StringUtils.isBlank(name)) {
+            return null;
+        }
+        if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
+            return super.map(name);
+        }
+        String tenantId = TenantHelper.getTenantId();
+        if (StringUtils.startsWith(name, tenantId)) {
+            // 濡傛灉瀛樺湪鍒欑洿鎺ヨ繑鍥�
+            return super.map(name);
+        }
+        return super.map(tenantId + ":" + name);
+    }
+
+    /**
+     * 鍘婚櫎鍓嶇紑
+     */
+    @Override
+    public String unmap(String name) {
+        String unmap = super.unmap(name);
+        if (StringUtils.isBlank(unmap)) {
+            return null;
+        }
+        if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
+            return super.unmap(name);
+        }
+        String tenantId = TenantHelper.getTenantId();
+        if (StringUtils.startsWith(unmap, tenantId)) {
+            // 濡傛灉瀛樺湪鍒欏垹闄�
+            return unmap.substring((tenantId + ":").length());
+        }
+        return unmap;
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java
new file mode 100644
index 0000000..e1784b5
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java
@@ -0,0 +1,110 @@
+package org.dromara.common.tenant.helper;
+
+import cn.dev33.satoken.context.SaHolder;
+import cn.dev33.satoken.spring.SpringMVCUtil;
+import cn.hutool.core.convert.Convert;
+import com.alibaba.ttl.TransmittableThreadLocal;
+import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy;
+import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
+import org.dromara.common.core.constant.GlobalConstants;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.redis.utils.RedisUtils;
+import org.dromara.common.satoken.utils.LoginHelper;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 绉熸埛鍔╂墜
+ *
+ * @author Lion Li
+ */
+@Slf4j
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class TenantHelper {
+
+    private static final String DYNAMIC_TENANT_KEY = GlobalConstants.GLOBAL_REDIS_KEY + "dynamicTenant";
+
+    private static final ThreadLocal<String> TEMP_DYNAMIC_TENANT = new TransmittableThreadLocal<>();
+
+    /**
+     * 绉熸埛鍔熻兘鏄惁鍚敤
+     */
+    public static boolean isEnable() {
+        return Convert.toBool(SpringUtils.getProperty("tenant.enable"), false);
+    }
+
+    /**
+     * 寮�鍚拷鐣ョ鎴�(寮�鍚悗闇�鎵嬪姩璋冪敤 {@link #disableIgnore()} 鍏抽棴)
+     */
+    public static void enableIgnore() {
+        InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().tenantLine(true).build());
+    }
+
+    /**
+     * 鍏抽棴蹇界暐绉熸埛
+     */
+    public static void disableIgnore() {
+        InterceptorIgnoreHelper.clearIgnoreStrategy();
+    }
+
+    /**
+     * 璁剧疆鍔ㄦ�佺鎴�(涓�鐩存湁鏁� 闇�瑕佹墜鍔ㄦ竻鐞�)
+     * <p>
+     * 濡傛灉涓洪潪web鐜 閭d箞鍙湪褰撳墠绾跨▼鍐呯敓鏁�
+     */
+    public static void setDynamic(String tenantId) {
+        if (!SpringMVCUtil.isWeb()) {
+            TEMP_DYNAMIC_TENANT.set(tenantId);
+            return;
+        }
+        String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId();
+        RedisUtils.setCacheObject(cacheKey, tenantId);
+        SaHolder.getStorage().set(cacheKey, tenantId);
+    }
+
+    /**
+     * 鑾峰彇鍔ㄦ�佺鎴�(涓�鐩存湁鏁� 闇�瑕佹墜鍔ㄦ竻鐞�)
+     * <p>
+     * 濡傛灉涓洪潪web鐜 閭d箞鍙湪褰撳墠绾跨▼鍐呯敓鏁�
+     */
+    public static String getDynamic() {
+        if (!SpringMVCUtil.isWeb()) {
+            return TEMP_DYNAMIC_TENANT.get();
+        }
+        String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId();
+        String tenantId = (String) SaHolder.getStorage().get(cacheKey);
+        if (StringUtils.isNotBlank(tenantId)) {
+            return tenantId;
+        }
+        tenantId = RedisUtils.getCacheObject(cacheKey);
+        SaHolder.getStorage().set(cacheKey, tenantId);
+        return tenantId;
+    }
+
+    /**
+     * 娓呴櫎鍔ㄦ�佺鎴�
+     */
+    public static void clearDynamic() {
+        if (!SpringMVCUtil.isWeb()) {
+            TEMP_DYNAMIC_TENANT.remove();
+            return;
+        }
+        String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId();
+        RedisUtils.deleteObject(cacheKey);
+        SaHolder.getStorage().delete(cacheKey);
+    }
+
+    /**
+     * 鑾峰彇褰撳墠绉熸埛id(鍔ㄦ�佺鎴蜂紭鍏�)
+     */
+    public static String getTenantId() {
+        String tenantId = TenantHelper.getDynamic();
+        if (StringUtils.isBlank(tenantId)) {
+            tenantId = LoginHelper.getTenantId();
+        }
+        return tenantId;
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/manager/TenantSpringCacheManager.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/manager/TenantSpringCacheManager.java
new file mode 100644
index 0000000..d230afc
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/manager/TenantSpringCacheManager.java
@@ -0,0 +1,32 @@
+package org.dromara.common.tenant.manager;
+
+import org.dromara.common.core.constant.GlobalConstants;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.redis.manager.PlusSpringCacheManager;
+import org.dromara.common.tenant.helper.TenantHelper;
+import org.springframework.cache.Cache;
+
+/**
+ * 閲嶅啓 cacheName 澶勭悊鏂规硶 鏀寔澶氱鎴�
+ *
+ * @author Lion Li
+ */
+public class TenantSpringCacheManager extends PlusSpringCacheManager {
+
+    public TenantSpringCacheManager() {
+    }
+
+    @Override
+    public Cache getCache(String name) {
+        if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
+            return super.getCache(name);
+        }
+        String tenantId = TenantHelper.getTenantId();
+        if (StringUtils.startsWith(name, tenantId)) {
+            // 濡傛灉瀛樺湪鍒欑洿鎺ヨ繑鍥�
+            return super.getCache(name);
+        }
+        return super.getCache(tenantId + ":" + name);
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/properties/TenantProperties.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/properties/TenantProperties.java
new file mode 100644
index 0000000..1675ccf
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/properties/TenantProperties.java
@@ -0,0 +1,27 @@
+package org.dromara.common.tenant.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.util.List;
+
+/**
+ * 绉熸埛 閰嶇疆灞炴��
+ *
+ * @author Lion Li
+ */
+@Data
+@ConfigurationProperties(prefix = "tenant")
+public class TenantProperties {
+
+    /**
+     * 鏄惁鍚敤
+     */
+    private Boolean enable;
+
+    /**
+     * 鎺掗櫎琛�
+     */
+    private List<String> excludes;
+
+}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-tenant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index 8f39d11..f837191 100644
--- a/ruoyi-common/ruoyi-common-tenant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-common/ruoyi-common-tenant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +1 @@
-com.ruoyi.common.tenant.config.TenantConfig
+org.dromara.common.tenant.config.TenantConfig
diff --git a/ruoyi-common/ruoyi-common-translation/pom.xml b/ruoyi-common/ruoyi-common-translation/pom.xml
index ce40aa2..28efd29 100644
--- a/ruoyi-common/ruoyi-common-translation/pom.xml
+++ b/ruoyi-common/ruoyi-common-translation/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-common</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -19,7 +19,7 @@
     <dependencies>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-json</artifactId>
         </dependency>
 
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/annotation/Translation.java b/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/annotation/Translation.java
deleted file mode 100644
index dbb469d..0000000
--- a/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/annotation/Translation.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.ruoyi.common.translation.annotation;
-
-import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
-import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-import com.ruoyi.common.translation.core.handler.TranslationHandler;
-
-import java.lang.annotation.*;
-
-/**
- * 閫氱敤缈昏瘧娉ㄨВ
- *
- * @author Lion Li
- */
-@Inherited
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.FIELD, ElementType.METHOD})
-@Documented
-@JacksonAnnotationsInside
-@JsonSerialize(using = TranslationHandler.class)
-public @interface Translation {
-
-    /**
-     * 绫诲瀷 (闇�涓庡疄鐜扮被涓婄殑 {@link com.ruoyi.common.translation.annotation.TranslationType} 娉ㄨВtype瀵瑰簲)
-     * <p>
-     * 榛樿鍙栧綋鍓嶅瓧娈电殑鍊� 濡傛灉璁剧疆浜� @{@link Translation#mapper()} 鍒欏彇鏄犲皠瀛楁鐨勫��
-     */
-    String type();
-
-    /**
-     * 鏄犲皠瀛楁 (濡傛灉涓嶄负绌哄垯鍙栨瀛楁鐨勫��)
-     */
-    String mapper() default "";
-
-    /**
-     * 鍏朵粬鏉′欢 渚嬪: 瀛楀吀type(sys_user_sex)
-     */
-    String other() default "";
-
-}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/annotation/TranslationType.java b/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/annotation/TranslationType.java
deleted file mode 100644
index 1b64e53..0000000
--- a/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/annotation/TranslationType.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.ruoyi.common.translation.annotation;
-
-import java.lang.annotation.*;
-
-/**
- * 缈昏瘧绫诲瀷娉ㄨВ (鏍囨敞鍒皗@link com.ruoyi.common.translation.core.TranslationInterface} 鐨勫疄鐜扮被)
- *
- * @author Lion Li
- */
-@Inherited
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.TYPE})
-@Documented
-public @interface TranslationType {
-
-    /**
-     * 绫诲瀷
-     */
-    String type();
-
-}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/config/TranslationConfig.java b/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/config/TranslationConfig.java
deleted file mode 100644
index a9aefe5..0000000
--- a/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/config/TranslationConfig.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.ruoyi.common.translation.config;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.ruoyi.common.translation.annotation.TranslationType;
-import com.ruoyi.common.translation.core.TranslationInterface;
-import com.ruoyi.common.translation.core.handler.TranslationBeanSerializerModifier;
-import com.ruoyi.common.translation.core.handler.TranslationHandler;
-import jakarta.annotation.PostConstruct;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 缈昏瘧妯″潡閰嶇疆绫�
- *
- * @author Lion Li
- */
-@Slf4j
-@AutoConfiguration
-public class TranslationConfig {
-
-    @Autowired
-    private List<TranslationInterface<?>> list;
-
-    @Autowired
-    private ObjectMapper objectMapper;
-
-    @PostConstruct
-    public void init() {
-        Map<String, TranslationInterface<?>> map = new HashMap<>(list.size());
-        for (TranslationInterface<?> trans : list) {
-            if (trans.getClass().isAnnotationPresent(TranslationType.class)) {
-                TranslationType annotation = trans.getClass().getAnnotation(TranslationType.class);
-                map.put(annotation.type(), trans);
-            } else {
-                log.warn(trans.getClass().getName() + " 缈昏瘧瀹炵幇绫绘湭鏍囨敞 TranslationType 娉ㄨВ!");
-            }
-        }
-        TranslationHandler.TRANSLATION_MAPPER.putAll(map);
-        // 璁剧疆 Bean 搴忓垪鍖栦慨鏀瑰櫒
-        objectMapper.setSerializerFactory(
-            objectMapper.getSerializerFactory()
-                .withSerializerModifier(new TranslationBeanSerializerModifier()));
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/constant/TransConstant.java b/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/constant/TransConstant.java
deleted file mode 100644
index 1cfec58..0000000
--- a/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/constant/TransConstant.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.ruoyi.common.translation.constant;
-
-/**
- * 缈昏瘧甯搁噺
- *
- * @author Lion Li
- */
-public interface TransConstant {
-
-    /**
-     * 鐢ㄦ埛id杞处鍙�
-     */
-    String USER_ID_TO_NAME = "user_id_to_name";
-
-    /**
-     * 閮ㄩ棬id杞悕绉�
-     */
-    String DEPT_ID_TO_NAME = "dept_id_to_name";
-
-    /**
-     * 瀛楀吀type杞琹abel
-     */
-    String DICT_TYPE_TO_LABEL = "dict_type_to_label";
-
-    /**
-     * ossId杞瑄rl
-     */
-    String OSS_ID_TO_URL = "oss_id_to_url";
-
-}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/core/TranslationInterface.java b/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/core/TranslationInterface.java
deleted file mode 100644
index b860ae4..0000000
--- a/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/core/TranslationInterface.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.ruoyi.common.translation.core;
-
-/**
- * 缈昏瘧鎺ュ彛 (瀹炵幇绫婚渶鏍囨敞 {@link com.ruoyi.common.translation.annotation.TranslationType} 娉ㄨВ鏍囨槑缈昏瘧绫诲瀷)
- *
- * @author Lion Li
- */
-public interface TranslationInterface<T> {
-
-    /**
-     * 缈昏瘧
-     *
-     * @param key   闇�瑕佽缈昏瘧鐨勯敭(涓嶄负绌�)
-     * @param other 鍏朵粬鍙傛暟
-     * @return 杩斿洖閿搴旂殑鍊�
-     */
-    T translation(Object key, String other);
-}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/core/handler/TranslationBeanSerializerModifier.java b/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/core/handler/TranslationBeanSerializerModifier.java
deleted file mode 100644
index fb3f6f7..0000000
--- a/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/core/handler/TranslationBeanSerializerModifier.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.ruoyi.common.translation.core.handler;
-
-import com.fasterxml.jackson.databind.BeanDescription;
-import com.fasterxml.jackson.databind.SerializationConfig;
-import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
-import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
-
-import java.util.List;
-
-/**
- * Bean 搴忓垪鍖栦慨鏀瑰櫒 瑙e喅 Null 琚崟鐙鐞嗛棶棰�
- *
- * @author Lion Li
- */
-public class TranslationBeanSerializerModifier extends BeanSerializerModifier {
-
-    @Override
-    public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc,
-                                                     List<BeanPropertyWriter> beanProperties) {
-        for (BeanPropertyWriter writer : beanProperties) {
-            // 濡傛灉搴忓垪鍖栧櫒涓� TranslationHandler 鐨勮瘽 灏� Null 鍊间篃浜ょ粰浠栧鐞�
-            if (writer.getSerializer() instanceof TranslationHandler serializer) {
-                writer.assignNullSerializer(serializer);
-            }
-        }
-        return beanProperties;
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/core/handler/TranslationHandler.java b/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/core/handler/TranslationHandler.java
deleted file mode 100644
index fcd122c..0000000
--- a/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/core/handler/TranslationHandler.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.ruoyi.common.translation.core.handler;
-
-import cn.hutool.core.util.ObjectUtil;
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.BeanProperty;
-import com.fasterxml.jackson.databind.JsonMappingException;
-import com.fasterxml.jackson.databind.JsonSerializer;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import com.fasterxml.jackson.databind.ser.ContextualSerializer;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.core.utils.reflect.ReflectUtils;
-import com.ruoyi.common.translation.annotation.Translation;
-import com.ruoyi.common.translation.core.TranslationInterface;
-import lombok.extern.slf4j.Slf4j;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * 缈昏瘧澶勭悊鍣�
- *
- * @author Lion Li
- */
-@Slf4j
-public class TranslationHandler extends JsonSerializer<Object> implements ContextualSerializer {
-
-    /**
-     * 鍏ㄥ眬缈昏瘧瀹炵幇绫绘槧灏勫櫒
-     */
-    public static final Map<String, TranslationInterface<?>> TRANSLATION_MAPPER = new ConcurrentHashMap<>();
-
-    private Translation translation;
-
-    @Override
-    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
-        TranslationInterface<?> trans = TRANSLATION_MAPPER.get(translation.type());
-        if (ObjectUtil.isNotNull(trans)) {
-            // 濡傛灉鏄犲皠瀛楁涓嶄负绌� 鍒欏彇鏄犲皠瀛楁鐨勫��
-            if (StringUtils.isNotBlank(translation.mapper())) {
-                value = ReflectUtils.invokeGetter(gen.getCurrentValue(), translation.mapper());
-            }
-            // 濡傛灉涓� null 鐩存帴鍐欏嚭
-            if (ObjectUtil.isNull(value)) {
-                gen.writeNull();
-                return;
-            }
-            Object result = trans.translation(value, translation.other());
-            gen.writeObject(result);
-        } else {
-            gen.writeObject(value);
-        }
-    }
-
-    @Override
-    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
-        Translation translation = property.getAnnotation(Translation.class);
-        if (Objects.nonNull(translation)) {
-            this.translation = translation;
-            return this;
-        }
-        return prov.findValueSerializer(property.getType(), property);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/core/impl/DeptNameTranslationImpl.java b/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/core/impl/DeptNameTranslationImpl.java
deleted file mode 100644
index 4529691..0000000
--- a/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/core/impl/DeptNameTranslationImpl.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.ruoyi.common.translation.core.impl;
-
-import com.ruoyi.common.core.service.DeptService;
-import com.ruoyi.common.translation.annotation.TranslationType;
-import com.ruoyi.common.translation.constant.TransConstant;
-import com.ruoyi.common.translation.core.TranslationInterface;
-import lombok.AllArgsConstructor;
-
-/**
- * 閮ㄩ棬缈昏瘧瀹炵幇
- *
- * @author Lion Li
- */
-@AllArgsConstructor
-@TranslationType(type = TransConstant.DEPT_ID_TO_NAME)
-public class DeptNameTranslationImpl implements TranslationInterface<String> {
-
-    private final DeptService deptService;
-
-    public String translation(Object key, String other) {
-        if (key instanceof String ids) {
-            return deptService.selectDeptNameByIds(ids);
-        } else if (key instanceof Long id) {
-            return deptService.selectDeptNameByIds(id.toString());
-        }
-        return null;
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/core/impl/DictTypeTranslationImpl.java b/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/core/impl/DictTypeTranslationImpl.java
deleted file mode 100644
index bf1bf09..0000000
--- a/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/core/impl/DictTypeTranslationImpl.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.ruoyi.common.translation.core.impl;
-
-import com.ruoyi.common.core.service.DictService;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.translation.annotation.TranslationType;
-import com.ruoyi.common.translation.constant.TransConstant;
-import com.ruoyi.common.translation.core.TranslationInterface;
-import lombok.AllArgsConstructor;
-import org.springframework.stereotype.Component;
-
-/**
- * 瀛楀吀缈昏瘧瀹炵幇
- *
- * @author Lion Li
- */
-@AllArgsConstructor
-@TranslationType(type = TransConstant.DICT_TYPE_TO_LABEL)
-public class DictTypeTranslationImpl implements TranslationInterface<String> {
-
-    private final DictService dictService;
-
-    public String translation(Object key, String other) {
-        if (key instanceof String dictValue && StringUtils.isNotBlank(other)) {
-            return dictService.getDictLabel(other, dictValue);
-        }
-        return null;
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/core/impl/OssUrlTranslationImpl.java b/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/core/impl/OssUrlTranslationImpl.java
deleted file mode 100644
index e0d2781..0000000
--- a/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/core/impl/OssUrlTranslationImpl.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.ruoyi.common.translation.core.impl;
-
-import com.ruoyi.common.core.service.OssService;
-import com.ruoyi.common.translation.annotation.TranslationType;
-import com.ruoyi.common.translation.constant.TransConstant;
-import com.ruoyi.common.translation.core.TranslationInterface;
-import lombok.AllArgsConstructor;
-import org.springframework.stereotype.Component;
-
-/**
- * OSS缈昏瘧瀹炵幇
- *
- * @author Lion Li
- */
-@AllArgsConstructor
-@TranslationType(type = TransConstant.OSS_ID_TO_URL)
-public class OssUrlTranslationImpl implements TranslationInterface<String> {
-
-    private final OssService ossService;
-
-    public String translation(Object key, String other) {
-        if (key instanceof String ids) {
-            return ossService.selectUrlByIds(ids);
-        } else if (key instanceof Long id) {
-            return ossService.selectUrlByIds(id.toString());
-        }
-        return null;
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/core/impl/UserNameTranslationImpl.java b/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/core/impl/UserNameTranslationImpl.java
deleted file mode 100644
index f37a3cb..0000000
--- a/ruoyi-common/ruoyi-common-translation/src/main/java/com/ruoyi/common/translation/core/impl/UserNameTranslationImpl.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.ruoyi.common.translation.core.impl;
-
-import com.ruoyi.common.core.service.UserService;
-import com.ruoyi.common.translation.annotation.TranslationType;
-import com.ruoyi.common.translation.constant.TransConstant;
-import com.ruoyi.common.translation.core.TranslationInterface;
-import lombok.AllArgsConstructor;
-
-/**
- * 鐢ㄦ埛鍚嶇炕璇戝疄鐜�
- *
- * @author Lion Li
- */
-@AllArgsConstructor
-@TranslationType(type = TransConstant.USER_ID_TO_NAME)
-public class UserNameTranslationImpl implements TranslationInterface<String> {
-
-    private final UserService userService;
-
-    public String translation(Object key, String other) {
-        if (key instanceof Long id) {
-            return userService.selectUserNameById(id);
-        }
-        return null;
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/annotation/Translation.java b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/annotation/Translation.java
new file mode 100644
index 0000000..c24aa6f
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/annotation/Translation.java
@@ -0,0 +1,39 @@
+package org.dromara.common.translation.annotation;
+
+import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import org.dromara.common.translation.core.handler.TranslationHandler;
+
+import java.lang.annotation.*;
+
+/**
+ * 閫氱敤缈昏瘧娉ㄨВ
+ *
+ * @author Lion Li
+ */
+@Inherited
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD, ElementType.METHOD})
+@Documented
+@JacksonAnnotationsInside
+@JsonSerialize(using = TranslationHandler.class)
+public @interface Translation {
+
+    /**
+     * 绫诲瀷 (闇�涓庡疄鐜扮被涓婄殑 {@link TranslationType} 娉ㄨВtype瀵瑰簲)
+     * <p>
+     * 榛樿鍙栧綋鍓嶅瓧娈电殑鍊� 濡傛灉璁剧疆浜� @{@link Translation#mapper()} 鍒欏彇鏄犲皠瀛楁鐨勫��
+     */
+    String type();
+
+    /**
+     * 鏄犲皠瀛楁 (濡傛灉涓嶄负绌哄垯鍙栨瀛楁鐨勫��)
+     */
+    String mapper() default "";
+
+    /**
+     * 鍏朵粬鏉′欢 渚嬪: 瀛楀吀type(sys_user_sex)
+     */
+    String other() default "";
+
+}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/annotation/TranslationType.java b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/annotation/TranslationType.java
new file mode 100644
index 0000000..43bfab0
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/annotation/TranslationType.java
@@ -0,0 +1,23 @@
+package org.dromara.common.translation.annotation;
+
+import org.dromara.common.translation.core.TranslationInterface;
+
+import java.lang.annotation.*;
+
+/**
+ * 缈昏瘧绫诲瀷娉ㄨВ (鏍囨敞鍒皗@link TranslationInterface} 鐨勫疄鐜扮被)
+ *
+ * @author Lion Li
+ */
+@Inherited
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+@Documented
+public @interface TranslationType {
+
+    /**
+     * 绫诲瀷
+     */
+    String type();
+
+}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/config/TranslationConfig.java b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/config/TranslationConfig.java
new file mode 100644
index 0000000..5dcd0c1
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/config/TranslationConfig.java
@@ -0,0 +1,50 @@
+package org.dromara.common.translation.config;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.dromara.common.translation.annotation.TranslationType;
+import org.dromara.common.translation.core.TranslationInterface;
+import org.dromara.common.translation.core.handler.TranslationBeanSerializerModifier;
+import org.dromara.common.translation.core.handler.TranslationHandler;
+import jakarta.annotation.PostConstruct;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 缈昏瘧妯″潡閰嶇疆绫�
+ *
+ * @author Lion Li
+ */
+@Slf4j
+@AutoConfiguration
+public class TranslationConfig {
+
+    @Autowired
+    private List<TranslationInterface<?>> list;
+
+    @Autowired
+    private ObjectMapper objectMapper;
+
+    @PostConstruct
+    public void init() {
+        Map<String, TranslationInterface<?>> map = new HashMap<>(list.size());
+        for (TranslationInterface<?> trans : list) {
+            if (trans.getClass().isAnnotationPresent(TranslationType.class)) {
+                TranslationType annotation = trans.getClass().getAnnotation(TranslationType.class);
+                map.put(annotation.type(), trans);
+            } else {
+                log.warn(trans.getClass().getName() + " 缈昏瘧瀹炵幇绫绘湭鏍囨敞 TranslationType 娉ㄨВ!");
+            }
+        }
+        TranslationHandler.TRANSLATION_MAPPER.putAll(map);
+        // 璁剧疆 Bean 搴忓垪鍖栦慨鏀瑰櫒
+        objectMapper.setSerializerFactory(
+            objectMapper.getSerializerFactory()
+                .withSerializerModifier(new TranslationBeanSerializerModifier()));
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java
new file mode 100644
index 0000000..25df1c9
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java
@@ -0,0 +1,30 @@
+package org.dromara.common.translation.constant;
+
+/**
+ * 缈昏瘧甯搁噺
+ *
+ * @author Lion Li
+ */
+public interface TransConstant {
+
+    /**
+     * 鐢ㄦ埛id杞处鍙�
+     */
+    String USER_ID_TO_NAME = "user_id_to_name";
+
+    /**
+     * 閮ㄩ棬id杞悕绉�
+     */
+    String DEPT_ID_TO_NAME = "dept_id_to_name";
+
+    /**
+     * 瀛楀吀type杞琹abel
+     */
+    String DICT_TYPE_TO_LABEL = "dict_type_to_label";
+
+    /**
+     * ossId杞瑄rl
+     */
+    String OSS_ID_TO_URL = "oss_id_to_url";
+
+}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/TranslationInterface.java b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/TranslationInterface.java
new file mode 100644
index 0000000..e4d6dd3
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/TranslationInterface.java
@@ -0,0 +1,20 @@
+package org.dromara.common.translation.core;
+
+import org.dromara.common.translation.annotation.TranslationType;
+
+/**
+ * 缈昏瘧鎺ュ彛 (瀹炵幇绫婚渶鏍囨敞 {@link TranslationType} 娉ㄨВ鏍囨槑缈昏瘧绫诲瀷)
+ *
+ * @author Lion Li
+ */
+public interface TranslationInterface<T> {
+
+    /**
+     * 缈昏瘧
+     *
+     * @param key   闇�瑕佽缈昏瘧鐨勯敭(涓嶄负绌�)
+     * @param other 鍏朵粬鍙傛暟
+     * @return 杩斿洖閿搴旂殑鍊�
+     */
+    T translation(Object key, String other);
+}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/handler/TranslationBeanSerializerModifier.java b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/handler/TranslationBeanSerializerModifier.java
new file mode 100644
index 0000000..727672f
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/handler/TranslationBeanSerializerModifier.java
@@ -0,0 +1,29 @@
+package org.dromara.common.translation.core.handler;
+
+import com.fasterxml.jackson.databind.BeanDescription;
+import com.fasterxml.jackson.databind.SerializationConfig;
+import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
+import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
+
+import java.util.List;
+
+/**
+ * Bean 搴忓垪鍖栦慨鏀瑰櫒 瑙e喅 Null 琚崟鐙鐞嗛棶棰�
+ *
+ * @author Lion Li
+ */
+public class TranslationBeanSerializerModifier extends BeanSerializerModifier {
+
+    @Override
+    public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc,
+                                                     List<BeanPropertyWriter> beanProperties) {
+        for (BeanPropertyWriter writer : beanProperties) {
+            // 濡傛灉搴忓垪鍖栧櫒涓� TranslationHandler 鐨勮瘽 灏� Null 鍊间篃浜ょ粰浠栧鐞�
+            if (writer.getSerializer() instanceof TranslationHandler serializer) {
+                writer.assignNullSerializer(serializer);
+            }
+        }
+        return beanProperties;
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/handler/TranslationHandler.java b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/handler/TranslationHandler.java
new file mode 100644
index 0000000..bb9615b
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/handler/TranslationHandler.java
@@ -0,0 +1,65 @@
+package org.dromara.common.translation.core.handler;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.ContextualSerializer;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.core.utils.reflect.ReflectUtils;
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.common.translation.core.TranslationInterface;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 缈昏瘧澶勭悊鍣�
+ *
+ * @author Lion Li
+ */
+@Slf4j
+public class TranslationHandler extends JsonSerializer<Object> implements ContextualSerializer {
+
+    /**
+     * 鍏ㄥ眬缈昏瘧瀹炵幇绫绘槧灏勫櫒
+     */
+    public static final Map<String, TranslationInterface<?>> TRANSLATION_MAPPER = new ConcurrentHashMap<>();
+
+    private Translation translation;
+
+    @Override
+    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
+        TranslationInterface<?> trans = TRANSLATION_MAPPER.get(translation.type());
+        if (ObjectUtil.isNotNull(trans)) {
+            // 濡傛灉鏄犲皠瀛楁涓嶄负绌� 鍒欏彇鏄犲皠瀛楁鐨勫��
+            if (StringUtils.isNotBlank(translation.mapper())) {
+                value = ReflectUtils.invokeGetter(gen.getCurrentValue(), translation.mapper());
+            }
+            // 濡傛灉涓� null 鐩存帴鍐欏嚭
+            if (ObjectUtil.isNull(value)) {
+                gen.writeNull();
+                return;
+            }
+            Object result = trans.translation(value, translation.other());
+            gen.writeObject(result);
+        } else {
+            gen.writeObject(value);
+        }
+    }
+
+    @Override
+    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
+        Translation translation = property.getAnnotation(Translation.class);
+        if (Objects.nonNull(translation)) {
+            this.translation = translation;
+            return this;
+        }
+        return prov.findValueSerializer(property.getType(), property);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/DeptNameTranslationImpl.java b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/DeptNameTranslationImpl.java
new file mode 100644
index 0000000..2502104
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/DeptNameTranslationImpl.java
@@ -0,0 +1,28 @@
+package org.dromara.common.translation.core.impl;
+
+import org.dromara.common.core.service.DeptService;
+import org.dromara.common.translation.annotation.TranslationType;
+import org.dromara.common.translation.constant.TransConstant;
+import org.dromara.common.translation.core.TranslationInterface;
+import lombok.AllArgsConstructor;
+
+/**
+ * 閮ㄩ棬缈昏瘧瀹炵幇
+ *
+ * @author Lion Li
+ */
+@AllArgsConstructor
+@TranslationType(type = TransConstant.DEPT_ID_TO_NAME)
+public class DeptNameTranslationImpl implements TranslationInterface<String> {
+
+    private final DeptService deptService;
+
+    public String translation(Object key, String other) {
+        if (key instanceof String ids) {
+            return deptService.selectDeptNameByIds(ids);
+        } else if (key instanceof Long id) {
+            return deptService.selectDeptNameByIds(id.toString());
+        }
+        return null;
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/DictTypeTranslationImpl.java b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/DictTypeTranslationImpl.java
new file mode 100644
index 0000000..4fc4adc
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/DictTypeTranslationImpl.java
@@ -0,0 +1,27 @@
+package org.dromara.common.translation.core.impl;
+
+import org.dromara.common.core.service.DictService;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.translation.annotation.TranslationType;
+import org.dromara.common.translation.constant.TransConstant;
+import org.dromara.common.translation.core.TranslationInterface;
+import lombok.AllArgsConstructor;
+
+/**
+ * 瀛楀吀缈昏瘧瀹炵幇
+ *
+ * @author Lion Li
+ */
+@AllArgsConstructor
+@TranslationType(type = TransConstant.DICT_TYPE_TO_LABEL)
+public class DictTypeTranslationImpl implements TranslationInterface<String> {
+
+    private final DictService dictService;
+
+    public String translation(Object key, String other) {
+        if (key instanceof String dictValue && StringUtils.isNotBlank(other)) {
+            return dictService.getDictLabel(other, dictValue);
+        }
+        return null;
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/OssUrlTranslationImpl.java b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/OssUrlTranslationImpl.java
new file mode 100644
index 0000000..f81aacb
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/OssUrlTranslationImpl.java
@@ -0,0 +1,28 @@
+package org.dromara.common.translation.core.impl;
+
+import org.dromara.common.core.service.OssService;
+import org.dromara.common.translation.annotation.TranslationType;
+import org.dromara.common.translation.constant.TransConstant;
+import org.dromara.common.translation.core.TranslationInterface;
+import lombok.AllArgsConstructor;
+
+/**
+ * OSS缈昏瘧瀹炵幇
+ *
+ * @author Lion Li
+ */
+@AllArgsConstructor
+@TranslationType(type = TransConstant.OSS_ID_TO_URL)
+public class OssUrlTranslationImpl implements TranslationInterface<String> {
+
+    private final OssService ossService;
+
+    public String translation(Object key, String other) {
+        if (key instanceof String ids) {
+            return ossService.selectUrlByIds(ids);
+        } else if (key instanceof Long id) {
+            return ossService.selectUrlByIds(id.toString());
+        }
+        return null;
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/UserNameTranslationImpl.java b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/UserNameTranslationImpl.java
new file mode 100644
index 0000000..8f0ebb3
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/UserNameTranslationImpl.java
@@ -0,0 +1,26 @@
+package org.dromara.common.translation.core.impl;
+
+import org.dromara.common.core.service.UserService;
+import org.dromara.common.translation.annotation.TranslationType;
+import org.dromara.common.translation.constant.TransConstant;
+import org.dromara.common.translation.core.TranslationInterface;
+import lombok.AllArgsConstructor;
+
+/**
+ * 鐢ㄦ埛鍚嶇炕璇戝疄鐜�
+ *
+ * @author Lion Li
+ */
+@AllArgsConstructor
+@TranslationType(type = TransConstant.USER_ID_TO_NAME)
+public class UserNameTranslationImpl implements TranslationInterface<String> {
+
+    private final UserService userService;
+
+    public String translation(Object key, String other) {
+        if (key instanceof Long id) {
+            return userService.selectUserNameById(id);
+        }
+        return null;
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index fe396d4..45844e0 100644
--- a/ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1,5 +1,5 @@
-com.ruoyi.common.translation.config.TranslationConfig
-com.ruoyi.common.translation.core.impl.DeptNameTranslationImpl
-com.ruoyi.common.translation.core.impl.DictTypeTranslationImpl
-com.ruoyi.common.translation.core.impl.OssUrlTranslationImpl
-com.ruoyi.common.translation.core.impl.UserNameTranslationImpl
+org.dromara.common.translation.config.TranslationConfig
+org.dromara.common.translation.core.impl.DeptNameTranslationImpl
+org.dromara.common.translation.core.impl.DictTypeTranslationImpl
+org.dromara.common.translation.core.impl.OssUrlTranslationImpl
+org.dromara.common.translation.core.impl.UserNameTranslationImpl
diff --git a/ruoyi-common/ruoyi-common-web/pom.xml b/ruoyi-common/ruoyi-common-web/pom.xml
index 97626fa..fd81a11 100644
--- a/ruoyi-common/ruoyi-common-web/pom.xml
+++ b/ruoyi-common/ruoyi-common-web/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-common</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -18,12 +18,12 @@
 
     <dependencies>
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-json</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-redis</artifactId>
         </dependency>
 
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/config/CaptchaConfig.java b/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/config/CaptchaConfig.java
deleted file mode 100644
index 5b2eba6..0000000
--- a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/config/CaptchaConfig.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.ruoyi.common.web.config;
-
-import cn.hutool.captcha.CaptchaUtil;
-import cn.hutool.captcha.CircleCaptcha;
-import cn.hutool.captcha.LineCaptcha;
-import cn.hutool.captcha.ShearCaptcha;
-import com.ruoyi.common.web.config.properties.CaptchaProperties;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Lazy;
-
-import java.awt.*;
-
-/**
- * 楠岃瘉鐮侀厤缃�
- *
- * @author Lion Li
- */
-@AutoConfiguration
-@EnableConfigurationProperties(CaptchaProperties.class)
-public class CaptchaConfig {
-
-    private static final int WIDTH = 160;
-    private static final int HEIGHT = 60;
-    private static final Color BACKGROUND = Color.PINK;
-    private static final Font FONT = new Font("Arial", Font.BOLD, 48);
-
-    /**
-     * 鍦嗗湀骞叉壈楠岃瘉鐮�
-     */
-    @Lazy
-    @Bean
-    public CircleCaptcha circleCaptcha() {
-        CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(WIDTH, HEIGHT);
-        captcha.setBackground(BACKGROUND);
-        captcha.setFont(FONT);
-        return captcha;
-    }
-
-    /**
-     * 绾挎骞叉壈鐨勯獙璇佺爜
-     */
-    @Lazy
-    @Bean
-    public LineCaptcha lineCaptcha() {
-        LineCaptcha captcha = CaptchaUtil.createLineCaptcha(WIDTH, HEIGHT);
-        captcha.setBackground(BACKGROUND);
-        captcha.setFont(FONT);
-        return captcha;
-    }
-
-    /**
-     * 鎵洸骞叉壈楠岃瘉鐮�
-     */
-    @Lazy
-    @Bean
-    public ShearCaptcha shearCaptcha() {
-        ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(WIDTH, HEIGHT);
-        captcha.setBackground(BACKGROUND);
-        captcha.setFont(FONT);
-        return captcha;
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/config/FilterConfig.java b/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/config/FilterConfig.java
deleted file mode 100644
index 7444f73..0000000
--- a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/config/FilterConfig.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package com.ruoyi.common.web.config;
-
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.web.config.properties.XssProperties;
-import com.ruoyi.common.web.filter.RepeatableFilter;
-import com.ruoyi.common.web.filter.XssFilter;
-import jakarta.servlet.DispatcherType;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.boot.web.servlet.FilterRegistrationBean;
-import org.springframework.context.annotation.Bean;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Filter閰嶇疆
- *
- * @author Lion Li
- */
-@AutoConfiguration
-@EnableConfigurationProperties(XssProperties.class)
-public class FilterConfig {
-
-    @SuppressWarnings({"rawtypes", "unchecked"})
-    @Bean
-    @ConditionalOnProperty(value = "xss.enabled", havingValue = "true")
-    public FilterRegistrationBean xssFilterRegistration(XssProperties xssProperties) {
-        FilterRegistrationBean registration = new FilterRegistrationBean();
-        registration.setDispatcherTypes(DispatcherType.REQUEST);
-        registration.setFilter(new XssFilter());
-        registration.addUrlPatterns(StringUtils.split(xssProperties.getUrlPatterns(), StringUtils.SEPARATOR));
-        registration.setName("xssFilter");
-        registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);
-        Map<String, String> initParameters = new HashMap<>();
-        initParameters.put("excludes", xssProperties.getExcludes());
-        registration.setInitParameters(initParameters);
-        return registration;
-    }
-
-    @SuppressWarnings({"rawtypes", "unchecked"})
-    @Bean
-    public FilterRegistrationBean someFilterRegistration() {
-        FilterRegistrationBean registration = new FilterRegistrationBean();
-        registration.setFilter(new RepeatableFilter());
-        registration.addUrlPatterns("/*");
-        registration.setName("repeatableFilter");
-        registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE);
-        return registration;
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/config/I18nConfig.java b/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/config/I18nConfig.java
deleted file mode 100644
index dd76619..0000000
--- a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/config/I18nConfig.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.ruoyi.common.web.config;
-
-import com.ruoyi.common.web.core.I18nLocaleResolver;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
-import org.springframework.context.annotation.Bean;
-import org.springframework.web.servlet.LocaleResolver;
-
-/**
- * 鍥介檯鍖栭厤缃�
- *
- * @author Lion Li
- */
-@AutoConfiguration(before = WebMvcAutoConfiguration.class)
-public class I18nConfig {
-
-    @Bean
-    public LocaleResolver localeResolver() {
-        return new I18nLocaleResolver();
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/config/ResourcesConfig.java b/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/config/ResourcesConfig.java
deleted file mode 100644
index a35ddb3..0000000
--- a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/config/ResourcesConfig.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.ruoyi.common.web.config;
-
-import com.ruoyi.common.web.interceptor.PlusWebInvokeTimeInterceptor;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.context.annotation.Bean;
-import org.springframework.web.cors.CorsConfiguration;
-import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
-import org.springframework.web.filter.CorsFilter;
-import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
-import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
-/**
- * 閫氱敤閰嶇疆
- *
- * @author Lion Li
- */
-@AutoConfiguration
-public class ResourcesConfig implements WebMvcConfigurer {
-
-    @Override
-    public void addInterceptors(InterceptorRegistry registry) {
-        // 鍏ㄥ眬璁块棶鎬ц兘鎷︽埅
-        registry.addInterceptor(new PlusWebInvokeTimeInterceptor());
-    }
-
-    @Override
-    public void addResourceHandlers(ResourceHandlerRegistry registry) {
-    }
-
-    /**
-     * 璺ㄥ煙閰嶇疆
-     */
-    @Bean
-    public CorsFilter corsFilter() {
-        CorsConfiguration config = new CorsConfiguration();
-        config.setAllowCredentials(true);
-        // 璁剧疆璁块棶婧愬湴鍧�
-        config.addAllowedOriginPattern("*");
-        // 璁剧疆璁块棶婧愯姹傚ご
-        config.addAllowedHeader("*");
-        // 璁剧疆璁块棶婧愯姹傛柟娉�
-        config.addAllowedMethod("*");
-        // 鏈夋晥鏈� 1800绉�
-        config.setMaxAge(1800L);
-        // 娣诲姞鏄犲皠璺緞锛屾嫤鎴竴鍒囪姹�
-        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
-        source.registerCorsConfiguration("/**", config);
-        // 杩斿洖鏂扮殑CorsFilter
-        return new CorsFilter(source);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/config/UndertowConfig.java b/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/config/UndertowConfig.java
deleted file mode 100644
index 6659c3c..0000000
--- a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/config/UndertowConfig.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.ruoyi.common.web.config;
-
-import io.undertow.server.DefaultByteBufferPool;
-import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
-import org.springframework.boot.web.server.WebServerFactoryCustomizer;
-
-/**
- * Undertow 鑷畾涔夐厤缃�
- *
- * @author Lion Li
- */
-@AutoConfiguration
-public class UndertowConfig implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
-
-    /**
-     * 璁剧疆 Undertow 鐨� websocket 缂撳啿姹�
-     */
-    @Override
-    public void customize(UndertowServletWebServerFactory factory) {
-        // 榛樿涓嶇洿鎺ュ垎閰嶅唴瀛� 濡傛灉椤圭洰涓娇鐢ㄤ簡 websocket 寤鸿鐩存帴鍒嗛厤
-        factory.addDeploymentInfoCustomizers(deploymentInfo -> {
-            WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo();
-            webSocketDeploymentInfo.setBuffers(new DefaultByteBufferPool(false, 512));
-            deploymentInfo.addServletContextAttribute("io.undertow.websockets.jsr.WebSocketDeploymentInfo", webSocketDeploymentInfo);
-        });
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/config/properties/CaptchaProperties.java b/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/config/properties/CaptchaProperties.java
deleted file mode 100644
index e4b8e15..0000000
--- a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/config/properties/CaptchaProperties.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.ruoyi.common.web.config.properties;
-
-import com.ruoyi.common.web.enums.CaptchaCategory;
-import com.ruoyi.common.web.enums.CaptchaType;
-import lombok.Data;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-/**
- * 楠岃瘉鐮� 閰嶇疆灞炴��
- *
- * @author Lion Li
- */
-@Data
-@ConfigurationProperties(prefix = "captcha")
-public class CaptchaProperties {
-
-    private Boolean enable;
-
-    /**
-     * 楠岃瘉鐮佺被鍨�
-     */
-    private CaptchaType type;
-
-    /**
-     * 楠岃瘉鐮佺被鍒�
-     */
-    private CaptchaCategory category;
-
-    /**
-     * 鏁板瓧楠岃瘉鐮佷綅鏁�
-     */
-    private Integer numberLength;
-
-    /**
-     * 瀛楃楠岃瘉鐮侀暱搴�
-     */
-    private Integer charLength;
-}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/config/properties/XssProperties.java b/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/config/properties/XssProperties.java
deleted file mode 100644
index 1978236..0000000
--- a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/config/properties/XssProperties.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.ruoyi.common.web.config.properties;
-
-import lombok.Data;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-/**
- * xss杩囨护 閰嶇疆灞炴��
- *
- * @author Lion Li
- */
-@Data
-@ConfigurationProperties(prefix = "xss")
-public class XssProperties {
-
-    /**
-     * 杩囨护寮�鍏�
-     */
-    private String enabled;
-
-    /**
-     * 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛�
-     */
-    private String excludes;
-
-    /**
-     * 鍖归厤閾炬帴
-     */
-    private String urlPatterns;
-
-}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/core/BaseController.java b/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/core/BaseController.java
deleted file mode 100644
index 0eac53a..0000000
--- a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/core/BaseController.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.ruoyi.common.web.core;
-
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.core.utils.StringUtils;
-
-/**
- * web灞傞�氱敤鏁版嵁澶勭悊
- *
- * @author Lion Li
- */
-public class BaseController {
-
-    /**
-     * 鍝嶅簲杩斿洖缁撴灉
-     *
-     * @param rows 褰卞搷琛屾暟
-     * @return 鎿嶄綔缁撴灉
-     */
-    protected R<Void> toAjax(int rows) {
-        return rows > 0 ? R.ok() : R.fail();
-    }
-
-    /**
-     * 鍝嶅簲杩斿洖缁撴灉
-     *
-     * @param result 缁撴灉
-     * @return 鎿嶄綔缁撴灉
-     */
-    protected R<Void> toAjax(boolean result) {
-        return result ? R.ok() : R.fail();
-    }
-
-    /**
-     * 椤甸潰璺宠浆
-     */
-    public String redirect(String url) {
-        return StringUtils.format("redirect:{}", url);
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/core/I18nLocaleResolver.java b/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/core/I18nLocaleResolver.java
deleted file mode 100644
index 6b741de..0000000
--- a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/core/I18nLocaleResolver.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.ruoyi.common.web.core;
-
-import org.springframework.web.servlet.LocaleResolver;
-
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import java.util.Locale;
-
-/**
- * 鑾峰彇璇锋眰澶村浗闄呭寲淇℃伅
- *
- * @author Lion Li
- */
-public class I18nLocaleResolver implements LocaleResolver {
-
-    @Override
-    public Locale resolveLocale(HttpServletRequest httpServletRequest) {
-        String language = httpServletRequest.getHeader("content-language");
-        Locale locale = Locale.getDefault();
-        if (language != null && language.length() > 0) {
-            String[] split = language.split("_");
-            locale = new Locale(split[0], split[1]);
-        }
-        return locale;
-    }
-
-    @Override
-    public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
-
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/enums/CaptchaCategory.java b/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/enums/CaptchaCategory.java
deleted file mode 100644
index 7fca5c2..0000000
--- a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/enums/CaptchaCategory.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.ruoyi.common.web.enums;
-
-import cn.hutool.captcha.AbstractCaptcha;
-import cn.hutool.captcha.CircleCaptcha;
-import cn.hutool.captcha.LineCaptcha;
-import cn.hutool.captcha.ShearCaptcha;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 楠岃瘉鐮佺被鍒�
- *
- * @author Lion Li
- */
-@Getter
-@AllArgsConstructor
-public enum CaptchaCategory {
-
-    /**
-     * 绾挎骞叉壈
-     */
-    LINE(LineCaptcha.class),
-
-    /**
-     * 鍦嗗湀骞叉壈
-     */
-    CIRCLE(CircleCaptcha.class),
-
-    /**
-     * 鎵洸骞叉壈
-     */
-    SHEAR(ShearCaptcha.class);
-
-    private final Class<? extends AbstractCaptcha> clazz;
-}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/enums/CaptchaType.java b/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/enums/CaptchaType.java
deleted file mode 100644
index f78d572..0000000
--- a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/enums/CaptchaType.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.ruoyi.common.web.enums;
-
-import cn.hutool.captcha.generator.CodeGenerator;
-import cn.hutool.captcha.generator.RandomGenerator;
-import com.ruoyi.common.web.utils.UnsignedMathGenerator;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 楠岃瘉鐮佺被鍨�
- *
- * @author Lion Li
- */
-@Getter
-@AllArgsConstructor
-public enum CaptchaType {
-
-    /**
-     * 鏁板瓧
-     */
-    MATH(UnsignedMathGenerator.class),
-
-    /**
-     * 瀛楃
-     */
-    CHAR(RandomGenerator.class);
-
-    private final Class<? extends CodeGenerator> clazz;
-}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/filter/RepeatableFilter.java b/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/filter/RepeatableFilter.java
deleted file mode 100644
index 60e98ef..0000000
--- a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/filter/RepeatableFilter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.ruoyi.common.web.filter;
-
-import com.ruoyi.common.core.utils.StringUtils;
-import org.springframework.http.MediaType;
-
-import jakarta.servlet.*;
-import jakarta.servlet.http.HttpServletRequest;
-import java.io.IOException;
-
-/**
- * Repeatable 杩囨护鍣�
- *
- * @author ruoyi
- */
-public class RepeatableFilter implements Filter {
-    @Override
-    public void init(FilterConfig filterConfig) throws ServletException {
-
-    }
-
-    @Override
-    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
-        throws IOException, ServletException {
-        ServletRequest requestWrapper = null;
-        if (request instanceof HttpServletRequest
-            && StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) {
-            requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response);
-        }
-        if (null == requestWrapper) {
-            chain.doFilter(request, response);
-        } else {
-            chain.doFilter(requestWrapper, response);
-        }
-    }
-
-    @Override
-    public void destroy() {
-
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/filter/RepeatedlyRequestWrapper.java b/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/filter/RepeatedlyRequestWrapper.java
deleted file mode 100644
index 32e6658..0000000
--- a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/filter/RepeatedlyRequestWrapper.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.ruoyi.common.web.filter;
-
-import cn.hutool.core.io.IoUtil;
-import com.ruoyi.common.core.constant.Constants;
-
-import jakarta.servlet.ReadListener;
-import jakarta.servlet.ServletInputStream;
-import jakarta.servlet.ServletResponse;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletRequestWrapper;
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-
-/**
- * 鏋勫缓鍙噸澶嶈鍙杋nputStream鐨剅equest
- *
- * @author ruoyi
- */
-public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper {
-    private final byte[] body;
-
-    public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException {
-        super(request);
-        request.setCharacterEncoding(Constants.UTF8);
-        response.setCharacterEncoding(Constants.UTF8);
-
-        body = IoUtil.readBytes(request.getInputStream(), false);
-    }
-
-    @Override
-    public BufferedReader getReader() throws IOException {
-        return new BufferedReader(new InputStreamReader(getInputStream()));
-    }
-
-    @Override
-    public ServletInputStream getInputStream() throws IOException {
-        final ByteArrayInputStream bais = new ByteArrayInputStream(body);
-        return new ServletInputStream() {
-            @Override
-            public int read() throws IOException {
-                return bais.read();
-            }
-
-            @Override
-            public int available() throws IOException {
-                return body.length;
-            }
-
-            @Override
-            public boolean isFinished() {
-                return false;
-            }
-
-            @Override
-            public boolean isReady() {
-                return false;
-            }
-
-            @Override
-            public void setReadListener(ReadListener readListener) {
-
-            }
-        };
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/filter/XssFilter.java b/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/filter/XssFilter.java
deleted file mode 100644
index 5ae7e7d..0000000
--- a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/filter/XssFilter.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.ruoyi.common.web.filter;
-
-import com.ruoyi.common.core.utils.StringUtils;
-import org.springframework.http.HttpMethod;
-
-import jakarta.servlet.*;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * 闃叉XSS鏀诲嚮鐨勮繃婊ゅ櫒
- *
- * @author ruoyi
- */
-public class XssFilter implements Filter {
-    /**
-     * 鎺掗櫎閾炬帴
-     */
-    public List<String> excludes = new ArrayList<>();
-
-    @Override
-    public void init(FilterConfig filterConfig) throws ServletException {
-        String tempExcludes = filterConfig.getInitParameter("excludes");
-        if (StringUtils.isNotEmpty(tempExcludes)) {
-            String[] url = tempExcludes.split(StringUtils.SEPARATOR);
-            for (int i = 0; url != null && i < url.length; i++) {
-                excludes.add(url[i]);
-            }
-        }
-    }
-
-    @Override
-    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
-        throws IOException, ServletException {
-        HttpServletRequest req = (HttpServletRequest) request;
-        HttpServletResponse resp = (HttpServletResponse) response;
-        if (handleExcludeURL(req, resp)) {
-            chain.doFilter(request, response);
-            return;
-        }
-        XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);
-        chain.doFilter(xssRequest, response);
-    }
-
-    private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) {
-        String url = request.getServletPath();
-        String method = request.getMethod();
-        // GET DELETE 涓嶈繃婊�
-        if (method == null || HttpMethod.GET.matches(method) || HttpMethod.DELETE.matches(method)) {
-            return true;
-        }
-        return StringUtils.matches(url, excludes);
-    }
-
-    @Override
-    public void destroy() {
-
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/filter/XssHttpServletRequestWrapper.java b/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/filter/XssHttpServletRequestWrapper.java
deleted file mode 100644
index a7d9f1e..0000000
--- a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/filter/XssHttpServletRequestWrapper.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package com.ruoyi.common.web.filter;
-
-import cn.hutool.core.io.IoUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.http.HtmlUtil;
-import com.ruoyi.common.core.utils.StringUtils;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.MediaType;
-
-import jakarta.servlet.ReadListener;
-import jakarta.servlet.ServletInputStream;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletRequestWrapper;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-
-/**
- * XSS杩囨护澶勭悊
- *
- * @author ruoyi
- */
-public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
-    /**
-     * @param request
-     */
-    public XssHttpServletRequestWrapper(HttpServletRequest request) {
-        super(request);
-    }
-
-    @Override
-    public String[] getParameterValues(String name) {
-        String[] values = super.getParameterValues(name);
-        if (values != null) {
-            int length = values.length;
-            String[] escapseValues = new String[length];
-            for (int i = 0; i < length; i++) {
-                // 闃瞲ss鏀诲嚮鍜岃繃婊ゅ墠鍚庣┖鏍�
-                escapseValues[i] = HtmlUtil.cleanHtmlTag(values[i]).trim();
-            }
-            return escapseValues;
-        }
-        return super.getParameterValues(name);
-    }
-
-    @Override
-    public ServletInputStream getInputStream() throws IOException {
-        // 闈瀓son绫诲瀷锛岀洿鎺ヨ繑鍥�
-        if (!isJsonRequest()) {
-            return super.getInputStream();
-        }
-
-        // 涓虹┖锛岀洿鎺ヨ繑鍥�
-        String json = StrUtil.str(IoUtil.readBytes(super.getInputStream(), false), StandardCharsets.UTF_8);
-        if (StringUtils.isEmpty(json)) {
-            return super.getInputStream();
-        }
-
-        // xss杩囨护
-        json = HtmlUtil.cleanHtmlTag(json).trim();
-        byte[] jsonBytes = json.getBytes(StandardCharsets.UTF_8);
-        final ByteArrayInputStream bis = IoUtil.toStream(jsonBytes);
-        return new ServletInputStream() {
-            @Override
-            public boolean isFinished() {
-                return true;
-            }
-
-            @Override
-            public boolean isReady() {
-                return true;
-            }
-
-            @Override
-            public int available() throws IOException {
-                return jsonBytes.length;
-            }
-
-            @Override
-            public void setReadListener(ReadListener readListener) {
-            }
-
-            @Override
-            public int read() throws IOException {
-                return bis.read();
-            }
-        };
-    }
-
-    /**
-     * 鏄惁鏄疛son璇锋眰
-     */
-    public boolean isJsonRequest() {
-        String header = super.getHeader(HttpHeaders.CONTENT_TYPE);
-        return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/interceptor/PlusWebInvokeTimeInterceptor.java b/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/interceptor/PlusWebInvokeTimeInterceptor.java
deleted file mode 100644
index a35fad4..0000000
--- a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/interceptor/PlusWebInvokeTimeInterceptor.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package com.ruoyi.common.web.interceptor;
-
-import cn.hutool.core.io.IoUtil;
-import cn.hutool.core.map.MapUtil;
-import com.alibaba.ttl.TransmittableThreadLocal;
-import com.ruoyi.common.core.utils.SpringUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.json.utils.JsonUtils;
-import com.ruoyi.common.web.filter.RepeatedlyRequestWrapper;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.time.StopWatch;
-import org.springframework.http.MediaType;
-import org.springframework.web.servlet.HandlerInterceptor;
-import org.springframework.web.servlet.ModelAndView;
-
-import java.io.BufferedReader;
-import java.util.Map;
-
-/**
- * web鐨勮皟鐢ㄦ椂闂寸粺璁℃嫤鎴櫒
- * dev鐜鏈夋晥
- *
- * @author Lion Li
- * @since 3.3.0
- */
-@Slf4j
-public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor {
-
-    private final String prodProfile = "prod";
-
-    private final TransmittableThreadLocal<StopWatch> invokeTimeTL = new TransmittableThreadLocal<>();
-
-    @Override
-    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
-        if (!prodProfile.equals(SpringUtils.getActiveProfile())) {
-            String url = request.getMethod() + " " + request.getRequestURI();
-
-            // 鎵撳嵃璇锋眰鍙傛暟
-            if (isJsonRequest(request)) {
-                String jsonParam = "";
-                if (request instanceof RepeatedlyRequestWrapper) {
-                    BufferedReader reader = request.getReader();
-                    jsonParam = IoUtil.read(reader);
-                }
-                log.debug("[PLUS]寮�濮嬭姹� => URL[{}],鍙傛暟绫诲瀷[json],鍙傛暟:[{}]", url, jsonParam);
-            } else {
-                Map<String, String[]> parameterMap = request.getParameterMap();
-                if (MapUtil.isNotEmpty(parameterMap)) {
-                    String parameters = JsonUtils.toJsonString(parameterMap);
-                    log.debug("[PLUS]寮�濮嬭姹� => URL[{}],鍙傛暟绫诲瀷[param],鍙傛暟:[{}]", url, parameters);
-                } else {
-                    log.debug("[PLUS]寮�濮嬭姹� => URL[{}],鏃犲弬鏁�", url);
-                }
-            }
-
-            StopWatch stopWatch = new StopWatch();
-            invokeTimeTL.set(stopWatch);
-            stopWatch.start();
-        }
-        return true;
-    }
-
-    @Override
-    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
-
-    }
-
-    @Override
-    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
-        if (!prodProfile.equals(SpringUtils.getActiveProfile())) {
-            StopWatch stopWatch = invokeTimeTL.get();
-            stopWatch.stop();
-            log.debug("[PLUS]缁撴潫璇锋眰 => URL[{}],鑰楁椂:[{}]姣", request.getMethod() + " " + request.getRequestURI(), stopWatch.getTime());
-            invokeTimeTL.remove();
-        }
-    }
-
-    /**
-     * 鍒ゆ柇鏈璇锋眰鐨勬暟鎹被鍨嬫槸鍚︿负json
-     *
-     * @param request request
-     * @return boolean
-     */
-    private boolean isJsonRequest(HttpServletRequest request) {
-        String contentType = request.getContentType();
-        if (contentType != null) {
-            return StringUtils.startsWithIgnoreCase(contentType, MediaType.APPLICATION_JSON_VALUE);
-        }
-        return false;
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/utils/UnsignedMathGenerator.java b/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/utils/UnsignedMathGenerator.java
deleted file mode 100644
index 06c3f3c..0000000
--- a/ruoyi-common/ruoyi-common-web/src/main/java/com/ruoyi/common/web/utils/UnsignedMathGenerator.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package com.ruoyi.common.web.utils;
-
-import cn.hutool.captcha.generator.CodeGenerator;
-import cn.hutool.core.math.Calculator;
-import cn.hutool.core.util.CharUtil;
-import cn.hutool.core.util.RandomUtil;
-import com.ruoyi.common.core.utils.StringUtils;
-
-import java.io.Serial;
-
-/**
- * 鏃犵鍙疯绠楃敓鎴愬櫒
- *
- * @author Lion Li
- */
-public class UnsignedMathGenerator implements CodeGenerator {
-
-    @Serial
-    private static final long serialVersionUID = -5514819971774091076L;
-
-    private static final String OPERATORS = "+-*";
-
-    /**
-     * 鍙備笌璁$畻鏁板瓧鏈�澶ч暱搴�
-     */
-    private final int numberLength;
-
-    /**
-     * 鏋勯��
-     */
-    public UnsignedMathGenerator() {
-        this(2);
-    }
-
-    /**
-     * 鏋勯��
-     *
-     * @param numberLength 鍙備笌璁$畻鏈�澶ф暟瀛椾綅鏁�
-     */
-    public UnsignedMathGenerator(int numberLength) {
-        this.numberLength = numberLength;
-    }
-
-    @Override
-    public String generate() {
-        final int limit = getLimit();
-        int a = RandomUtil.randomInt(limit);
-        int b = RandomUtil.randomInt(limit);
-        String max = Integer.toString(Math.max(a,b));
-        String min = Integer.toString(Math.min(a,b));
-        max = StringUtils.rightPad(max, this.numberLength, CharUtil.SPACE);
-        min = StringUtils.rightPad(min, this.numberLength, CharUtil.SPACE);
-
-        return max + RandomUtil.randomChar(OPERATORS) + min + '=';
-    }
-
-    @Override
-    public boolean verify(String code, String userInputCode) {
-        int result;
-        try {
-            result = Integer.parseInt(userInputCode);
-        } catch (NumberFormatException e) {
-            // 鐢ㄦ埛杈撳叆闈炴暟瀛�
-            return false;
-        }
-
-        final int calculateResult = (int) Calculator.conversion(code);
-        return result == calculateResult;
-    }
-
-    /**
-     * 鑾峰彇楠岃瘉鐮侀暱搴�
-     *
-     * @return 楠岃瘉鐮侀暱搴�
-     */
-    public int getLength() {
-        return this.numberLength * 2 + 2;
-    }
-
-    /**
-     * 鏍规嵁闀垮害鑾峰彇鍙備笌璁$畻鏁板瓧鏈�澶у��
-     *
-     * @return 鏈�澶у��
-     */
-    private int getLimit() {
-        return Integer.parseInt("1" + StringUtils.repeat('0', this.numberLength));
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/CaptchaConfig.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/CaptchaConfig.java
new file mode 100644
index 0000000..9225a51
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/CaptchaConfig.java
@@ -0,0 +1,65 @@
+package org.dromara.common.web.config;
+
+import cn.hutool.captcha.CaptchaUtil;
+import cn.hutool.captcha.CircleCaptcha;
+import cn.hutool.captcha.LineCaptcha;
+import cn.hutool.captcha.ShearCaptcha;
+import org.dromara.common.web.config.properties.CaptchaProperties;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Lazy;
+
+import java.awt.*;
+
+/**
+ * 楠岃瘉鐮侀厤缃�
+ *
+ * @author Lion Li
+ */
+@AutoConfiguration
+@EnableConfigurationProperties(CaptchaProperties.class)
+public class CaptchaConfig {
+
+    private static final int WIDTH = 160;
+    private static final int HEIGHT = 60;
+    private static final Color BACKGROUND = Color.PINK;
+    private static final Font FONT = new Font("Arial", Font.BOLD, 48);
+
+    /**
+     * 鍦嗗湀骞叉壈楠岃瘉鐮�
+     */
+    @Lazy
+    @Bean
+    public CircleCaptcha circleCaptcha() {
+        CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(WIDTH, HEIGHT);
+        captcha.setBackground(BACKGROUND);
+        captcha.setFont(FONT);
+        return captcha;
+    }
+
+    /**
+     * 绾挎骞叉壈鐨勯獙璇佺爜
+     */
+    @Lazy
+    @Bean
+    public LineCaptcha lineCaptcha() {
+        LineCaptcha captcha = CaptchaUtil.createLineCaptcha(WIDTH, HEIGHT);
+        captcha.setBackground(BACKGROUND);
+        captcha.setFont(FONT);
+        return captcha;
+    }
+
+    /**
+     * 鎵洸骞叉壈楠岃瘉鐮�
+     */
+    @Lazy
+    @Bean
+    public ShearCaptcha shearCaptcha() {
+        ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(WIDTH, HEIGHT);
+        captcha.setBackground(BACKGROUND);
+        captcha.setFont(FONT);
+        return captcha;
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/FilterConfig.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/FilterConfig.java
new file mode 100644
index 0000000..91fff76
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/FilterConfig.java
@@ -0,0 +1,53 @@
+package org.dromara.common.web.config;
+
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.web.config.properties.XssProperties;
+import org.dromara.common.web.filter.RepeatableFilter;
+import org.dromara.common.web.filter.XssFilter;
+import jakarta.servlet.DispatcherType;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Filter閰嶇疆
+ *
+ * @author Lion Li
+ */
+@AutoConfiguration
+@EnableConfigurationProperties(XssProperties.class)
+public class FilterConfig {
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    @Bean
+    @ConditionalOnProperty(value = "xss.enabled", havingValue = "true")
+    public FilterRegistrationBean xssFilterRegistration(XssProperties xssProperties) {
+        FilterRegistrationBean registration = new FilterRegistrationBean();
+        registration.setDispatcherTypes(DispatcherType.REQUEST);
+        registration.setFilter(new XssFilter());
+        registration.addUrlPatterns(StringUtils.split(xssProperties.getUrlPatterns(), StringUtils.SEPARATOR));
+        registration.setName("xssFilter");
+        registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);
+        Map<String, String> initParameters = new HashMap<>();
+        initParameters.put("excludes", xssProperties.getExcludes());
+        registration.setInitParameters(initParameters);
+        return registration;
+    }
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    @Bean
+    public FilterRegistrationBean someFilterRegistration() {
+        FilterRegistrationBean registration = new FilterRegistrationBean();
+        registration.setFilter(new RepeatableFilter());
+        registration.addUrlPatterns("/*");
+        registration.setName("repeatableFilter");
+        registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE);
+        return registration;
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/I18nConfig.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/I18nConfig.java
new file mode 100644
index 0000000..4e212cb
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/I18nConfig.java
@@ -0,0 +1,22 @@
+package org.dromara.common.web.config;
+
+import org.dromara.common.web.core.I18nLocaleResolver;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.servlet.LocaleResolver;
+
+/**
+ * 鍥介檯鍖栭厤缃�
+ *
+ * @author Lion Li
+ */
+@AutoConfiguration(before = WebMvcAutoConfiguration.class)
+public class I18nConfig {
+
+    @Bean
+    public LocaleResolver localeResolver() {
+        return new I18nLocaleResolver();
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/ResourcesConfig.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/ResourcesConfig.java
new file mode 100644
index 0000000..1b78ebc
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/ResourcesConfig.java
@@ -0,0 +1,52 @@
+package org.dromara.common.web.config;
+
+import org.dromara.common.web.interceptor.PlusWebInvokeTimeInterceptor;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * 閫氱敤閰嶇疆
+ *
+ * @author Lion Li
+ */
+@AutoConfiguration
+public class ResourcesConfig implements WebMvcConfigurer {
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        // 鍏ㄥ眬璁块棶鎬ц兘鎷︽埅
+        registry.addInterceptor(new PlusWebInvokeTimeInterceptor());
+    }
+
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry) {
+    }
+
+    /**
+     * 璺ㄥ煙閰嶇疆
+     */
+    @Bean
+    public CorsFilter corsFilter() {
+        CorsConfiguration config = new CorsConfiguration();
+        config.setAllowCredentials(true);
+        // 璁剧疆璁块棶婧愬湴鍧�
+        config.addAllowedOriginPattern("*");
+        // 璁剧疆璁块棶婧愯姹傚ご
+        config.addAllowedHeader("*");
+        // 璁剧疆璁块棶婧愯姹傛柟娉�
+        config.addAllowedMethod("*");
+        // 鏈夋晥鏈� 1800绉�
+        config.setMaxAge(1800L);
+        // 娣诲姞鏄犲皠璺緞锛屾嫤鎴竴鍒囪姹�
+        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+        source.registerCorsConfiguration("/**", config);
+        // 杩斿洖鏂扮殑CorsFilter
+        return new CorsFilter(source);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/UndertowConfig.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/UndertowConfig.java
new file mode 100644
index 0000000..421ce6d
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/UndertowConfig.java
@@ -0,0 +1,30 @@
+package org.dromara.common.web.config;
+
+import io.undertow.server.DefaultByteBufferPool;
+import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
+import org.springframework.boot.web.server.WebServerFactoryCustomizer;
+
+/**
+ * Undertow 鑷畾涔夐厤缃�
+ *
+ * @author Lion Li
+ */
+@AutoConfiguration
+public class UndertowConfig implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
+
+    /**
+     * 璁剧疆 Undertow 鐨� websocket 缂撳啿姹�
+     */
+    @Override
+    public void customize(UndertowServletWebServerFactory factory) {
+        // 榛樿涓嶇洿鎺ュ垎閰嶅唴瀛� 濡傛灉椤圭洰涓娇鐢ㄤ簡 websocket 寤鸿鐩存帴鍒嗛厤
+        factory.addDeploymentInfoCustomizers(deploymentInfo -> {
+            WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo();
+            webSocketDeploymentInfo.setBuffers(new DefaultByteBufferPool(false, 512));
+            deploymentInfo.addServletContextAttribute("io.undertow.websockets.jsr.WebSocketDeploymentInfo", webSocketDeploymentInfo);
+        });
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/properties/CaptchaProperties.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/properties/CaptchaProperties.java
new file mode 100644
index 0000000..bfc52f4
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/properties/CaptchaProperties.java
@@ -0,0 +1,38 @@
+package org.dromara.common.web.config.properties;
+
+import org.dromara.common.web.enums.CaptchaCategory;
+import org.dromara.common.web.enums.CaptchaType;
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * 楠岃瘉鐮� 閰嶇疆灞炴��
+ *
+ * @author Lion Li
+ */
+@Data
+@ConfigurationProperties(prefix = "captcha")
+public class CaptchaProperties {
+
+    private Boolean enable;
+
+    /**
+     * 楠岃瘉鐮佺被鍨�
+     */
+    private CaptchaType type;
+
+    /**
+     * 楠岃瘉鐮佺被鍒�
+     */
+    private CaptchaCategory category;
+
+    /**
+     * 鏁板瓧楠岃瘉鐮佷綅鏁�
+     */
+    private Integer numberLength;
+
+    /**
+     * 瀛楃楠岃瘉鐮侀暱搴�
+     */
+    private Integer charLength;
+}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/properties/XssProperties.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/properties/XssProperties.java
new file mode 100644
index 0000000..ecf4f33
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/properties/XssProperties.java
@@ -0,0 +1,30 @@
+package org.dromara.common.web.config.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * xss杩囨护 閰嶇疆灞炴��
+ *
+ * @author Lion Li
+ */
+@Data
+@ConfigurationProperties(prefix = "xss")
+public class XssProperties {
+
+    /**
+     * 杩囨护寮�鍏�
+     */
+    private String enabled;
+
+    /**
+     * 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛�
+     */
+    private String excludes;
+
+    /**
+     * 鍖归厤閾炬帴
+     */
+    private String urlPatterns;
+
+}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/core/BaseController.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/core/BaseController.java
new file mode 100644
index 0000000..fd01dda
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/core/BaseController.java
@@ -0,0 +1,40 @@
+package org.dromara.common.web.core;
+
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.utils.StringUtils;
+
+/**
+ * web灞傞�氱敤鏁版嵁澶勭悊
+ *
+ * @author Lion Li
+ */
+public class BaseController {
+
+    /**
+     * 鍝嶅簲杩斿洖缁撴灉
+     *
+     * @param rows 褰卞搷琛屾暟
+     * @return 鎿嶄綔缁撴灉
+     */
+    protected R<Void> toAjax(int rows) {
+        return rows > 0 ? R.ok() : R.fail();
+    }
+
+    /**
+     * 鍝嶅簲杩斿洖缁撴灉
+     *
+     * @param result 缁撴灉
+     * @return 鎿嶄綔缁撴灉
+     */
+    protected R<Void> toAjax(boolean result) {
+        return result ? R.ok() : R.fail();
+    }
+
+    /**
+     * 椤甸潰璺宠浆
+     */
+    public String redirect(String url) {
+        return StringUtils.format("redirect:{}", url);
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/core/I18nLocaleResolver.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/core/I18nLocaleResolver.java
new file mode 100644
index 0000000..98ddd06
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/core/I18nLocaleResolver.java
@@ -0,0 +1,31 @@
+package org.dromara.common.web.core;
+
+import org.springframework.web.servlet.LocaleResolver;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import java.util.Locale;
+
+/**
+ * 鑾峰彇璇锋眰澶村浗闄呭寲淇℃伅
+ *
+ * @author Lion Li
+ */
+public class I18nLocaleResolver implements LocaleResolver {
+
+    @Override
+    public Locale resolveLocale(HttpServletRequest httpServletRequest) {
+        String language = httpServletRequest.getHeader("content-language");
+        Locale locale = Locale.getDefault();
+        if (language != null && language.length() > 0) {
+            String[] split = language.split("_");
+            locale = new Locale(split[0], split[1]);
+        }
+        return locale;
+    }
+
+    @Override
+    public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
+
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/enums/CaptchaCategory.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/enums/CaptchaCategory.java
new file mode 100644
index 0000000..ecf2658
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/enums/CaptchaCategory.java
@@ -0,0 +1,35 @@
+package org.dromara.common.web.enums;
+
+import cn.hutool.captcha.AbstractCaptcha;
+import cn.hutool.captcha.CircleCaptcha;
+import cn.hutool.captcha.LineCaptcha;
+import cn.hutool.captcha.ShearCaptcha;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 楠岃瘉鐮佺被鍒�
+ *
+ * @author Lion Li
+ */
+@Getter
+@AllArgsConstructor
+public enum CaptchaCategory {
+
+    /**
+     * 绾挎骞叉壈
+     */
+    LINE(LineCaptcha.class),
+
+    /**
+     * 鍦嗗湀骞叉壈
+     */
+    CIRCLE(CircleCaptcha.class),
+
+    /**
+     * 鎵洸骞叉壈
+     */
+    SHEAR(ShearCaptcha.class);
+
+    private final Class<? extends AbstractCaptcha> clazz;
+}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/enums/CaptchaType.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/enums/CaptchaType.java
new file mode 100644
index 0000000..d0b7334
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/enums/CaptchaType.java
@@ -0,0 +1,29 @@
+package org.dromara.common.web.enums;
+
+import cn.hutool.captcha.generator.CodeGenerator;
+import cn.hutool.captcha.generator.RandomGenerator;
+import org.dromara.common.web.utils.UnsignedMathGenerator;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 楠岃瘉鐮佺被鍨�
+ *
+ * @author Lion Li
+ */
+@Getter
+@AllArgsConstructor
+public enum CaptchaType {
+
+    /**
+     * 鏁板瓧
+     */
+    MATH(UnsignedMathGenerator.class),
+
+    /**
+     * 瀛楃
+     */
+    CHAR(RandomGenerator.class);
+
+    private final Class<? extends CodeGenerator> clazz;
+}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/filter/RepeatableFilter.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/filter/RepeatableFilter.java
new file mode 100644
index 0000000..e0a3bf2
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/filter/RepeatableFilter.java
@@ -0,0 +1,40 @@
+package org.dromara.common.web.filter;
+
+import org.dromara.common.core.utils.StringUtils;
+import org.springframework.http.MediaType;
+
+import jakarta.servlet.*;
+import jakarta.servlet.http.HttpServletRequest;
+import java.io.IOException;
+
+/**
+ * Repeatable 杩囨护鍣�
+ *
+ * @author ruoyi
+ */
+public class RepeatableFilter implements Filter {
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException {
+
+    }
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+        throws IOException, ServletException {
+        ServletRequest requestWrapper = null;
+        if (request instanceof HttpServletRequest
+            && StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) {
+            requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response);
+        }
+        if (null == requestWrapper) {
+            chain.doFilter(request, response);
+        } else {
+            chain.doFilter(requestWrapper, response);
+        }
+    }
+
+    @Override
+    public void destroy() {
+
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/filter/RepeatedlyRequestWrapper.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/filter/RepeatedlyRequestWrapper.java
new file mode 100644
index 0000000..8933225
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/filter/RepeatedlyRequestWrapper.java
@@ -0,0 +1,68 @@
+package org.dromara.common.web.filter;
+
+import cn.hutool.core.io.IoUtil;
+import org.dromara.common.core.constant.Constants;
+
+import jakarta.servlet.ReadListener;
+import jakarta.servlet.ServletInputStream;
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletRequestWrapper;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+/**
+ * 鏋勫缓鍙噸澶嶈鍙杋nputStream鐨剅equest
+ *
+ * @author ruoyi
+ */
+public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper {
+    private final byte[] body;
+
+    public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException {
+        super(request);
+        request.setCharacterEncoding(Constants.UTF8);
+        response.setCharacterEncoding(Constants.UTF8);
+
+        body = IoUtil.readBytes(request.getInputStream(), false);
+    }
+
+    @Override
+    public BufferedReader getReader() throws IOException {
+        return new BufferedReader(new InputStreamReader(getInputStream()));
+    }
+
+    @Override
+    public ServletInputStream getInputStream() throws IOException {
+        final ByteArrayInputStream bais = new ByteArrayInputStream(body);
+        return new ServletInputStream() {
+            @Override
+            public int read() throws IOException {
+                return bais.read();
+            }
+
+            @Override
+            public int available() throws IOException {
+                return body.length;
+            }
+
+            @Override
+            public boolean isFinished() {
+                return false;
+            }
+
+            @Override
+            public boolean isReady() {
+                return false;
+            }
+
+            @Override
+            public void setReadListener(ReadListener readListener) {
+
+            }
+        };
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/filter/XssFilter.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/filter/XssFilter.java
new file mode 100644
index 0000000..a6cbe8c
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/filter/XssFilter.java
@@ -0,0 +1,62 @@
+package org.dromara.common.web.filter;
+
+import org.dromara.common.core.utils.StringUtils;
+import org.springframework.http.HttpMethod;
+
+import jakarta.servlet.*;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 闃叉XSS鏀诲嚮鐨勮繃婊ゅ櫒
+ *
+ * @author ruoyi
+ */
+public class XssFilter implements Filter {
+    /**
+     * 鎺掗櫎閾炬帴
+     */
+    public List<String> excludes = new ArrayList<>();
+
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException {
+        String tempExcludes = filterConfig.getInitParameter("excludes");
+        if (StringUtils.isNotEmpty(tempExcludes)) {
+            String[] url = tempExcludes.split(StringUtils.SEPARATOR);
+            for (int i = 0; url != null && i < url.length; i++) {
+                excludes.add(url[i]);
+            }
+        }
+    }
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+        throws IOException, ServletException {
+        HttpServletRequest req = (HttpServletRequest) request;
+        HttpServletResponse resp = (HttpServletResponse) response;
+        if (handleExcludeURL(req, resp)) {
+            chain.doFilter(request, response);
+            return;
+        }
+        XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);
+        chain.doFilter(xssRequest, response);
+    }
+
+    private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) {
+        String url = request.getServletPath();
+        String method = request.getMethod();
+        // GET DELETE 涓嶈繃婊�
+        if (method == null || HttpMethod.GET.matches(method) || HttpMethod.DELETE.matches(method)) {
+            return true;
+        }
+        return StringUtils.matches(url, excludes);
+    }
+
+    @Override
+    public void destroy() {
+
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/filter/XssHttpServletRequestWrapper.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/filter/XssHttpServletRequestWrapper.java
new file mode 100644
index 0000000..4a425c5
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/filter/XssHttpServletRequestWrapper.java
@@ -0,0 +1,97 @@
+package org.dromara.common.web.filter;
+
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HtmlUtil;
+import org.dromara.common.core.utils.StringUtils;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+
+import jakarta.servlet.ReadListener;
+import jakarta.servlet.ServletInputStream;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletRequestWrapper;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * XSS杩囨护澶勭悊
+ *
+ * @author ruoyi
+ */
+public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
+    /**
+     * @param request
+     */
+    public XssHttpServletRequestWrapper(HttpServletRequest request) {
+        super(request);
+    }
+
+    @Override
+    public String[] getParameterValues(String name) {
+        String[] values = super.getParameterValues(name);
+        if (values != null) {
+            int length = values.length;
+            String[] escapseValues = new String[length];
+            for (int i = 0; i < length; i++) {
+                // 闃瞲ss鏀诲嚮鍜岃繃婊ゅ墠鍚庣┖鏍�
+                escapseValues[i] = HtmlUtil.cleanHtmlTag(values[i]).trim();
+            }
+            return escapseValues;
+        }
+        return super.getParameterValues(name);
+    }
+
+    @Override
+    public ServletInputStream getInputStream() throws IOException {
+        // 闈瀓son绫诲瀷锛岀洿鎺ヨ繑鍥�
+        if (!isJsonRequest()) {
+            return super.getInputStream();
+        }
+
+        // 涓虹┖锛岀洿鎺ヨ繑鍥�
+        String json = StrUtil.str(IoUtil.readBytes(super.getInputStream(), false), StandardCharsets.UTF_8);
+        if (StringUtils.isEmpty(json)) {
+            return super.getInputStream();
+        }
+
+        // xss杩囨护
+        json = HtmlUtil.cleanHtmlTag(json).trim();
+        byte[] jsonBytes = json.getBytes(StandardCharsets.UTF_8);
+        final ByteArrayInputStream bis = IoUtil.toStream(jsonBytes);
+        return new ServletInputStream() {
+            @Override
+            public boolean isFinished() {
+                return true;
+            }
+
+            @Override
+            public boolean isReady() {
+                return true;
+            }
+
+            @Override
+            public int available() throws IOException {
+                return jsonBytes.length;
+            }
+
+            @Override
+            public void setReadListener(ReadListener readListener) {
+            }
+
+            @Override
+            public int read() throws IOException {
+                return bis.read();
+            }
+        };
+    }
+
+    /**
+     * 鏄惁鏄疛son璇锋眰
+     */
+    public boolean isJsonRequest() {
+        String header = super.getHeader(HttpHeaders.CONTENT_TYPE);
+        return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/interceptor/PlusWebInvokeTimeInterceptor.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/interceptor/PlusWebInvokeTimeInterceptor.java
new file mode 100644
index 0000000..5302035
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/interceptor/PlusWebInvokeTimeInterceptor.java
@@ -0,0 +1,94 @@
+package org.dromara.common.web.interceptor;
+
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.map.MapUtil;
+import com.alibaba.ttl.TransmittableThreadLocal;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.json.utils.JsonUtils;
+import org.dromara.common.web.filter.RepeatedlyRequestWrapper;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.time.StopWatch;
+import org.springframework.http.MediaType;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.ModelAndView;
+
+import java.io.BufferedReader;
+import java.util.Map;
+
+/**
+ * web鐨勮皟鐢ㄦ椂闂寸粺璁℃嫤鎴櫒
+ * dev鐜鏈夋晥
+ *
+ * @author Lion Li
+ * @since 3.3.0
+ */
+@Slf4j
+public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor {
+
+    private final String prodProfile = "prod";
+
+    private final TransmittableThreadLocal<StopWatch> invokeTimeTL = new TransmittableThreadLocal<>();
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+        if (!prodProfile.equals(SpringUtils.getActiveProfile())) {
+            String url = request.getMethod() + " " + request.getRequestURI();
+
+            // 鎵撳嵃璇锋眰鍙傛暟
+            if (isJsonRequest(request)) {
+                String jsonParam = "";
+                if (request instanceof RepeatedlyRequestWrapper) {
+                    BufferedReader reader = request.getReader();
+                    jsonParam = IoUtil.read(reader);
+                }
+                log.debug("[PLUS]寮�濮嬭姹� => URL[{}],鍙傛暟绫诲瀷[json],鍙傛暟:[{}]", url, jsonParam);
+            } else {
+                Map<String, String[]> parameterMap = request.getParameterMap();
+                if (MapUtil.isNotEmpty(parameterMap)) {
+                    String parameters = JsonUtils.toJsonString(parameterMap);
+                    log.debug("[PLUS]寮�濮嬭姹� => URL[{}],鍙傛暟绫诲瀷[param],鍙傛暟:[{}]", url, parameters);
+                } else {
+                    log.debug("[PLUS]寮�濮嬭姹� => URL[{}],鏃犲弬鏁�", url);
+                }
+            }
+
+            StopWatch stopWatch = new StopWatch();
+            invokeTimeTL.set(stopWatch);
+            stopWatch.start();
+        }
+        return true;
+    }
+
+    @Override
+    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
+
+    }
+
+    @Override
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
+        if (!prodProfile.equals(SpringUtils.getActiveProfile())) {
+            StopWatch stopWatch = invokeTimeTL.get();
+            stopWatch.stop();
+            log.debug("[PLUS]缁撴潫璇锋眰 => URL[{}],鑰楁椂:[{}]姣", request.getMethod() + " " + request.getRequestURI(), stopWatch.getTime());
+            invokeTimeTL.remove();
+        }
+    }
+
+    /**
+     * 鍒ゆ柇鏈璇锋眰鐨勬暟鎹被鍨嬫槸鍚︿负json
+     *
+     * @param request request
+     * @return boolean
+     */
+    private boolean isJsonRequest(HttpServletRequest request) {
+        String contentType = request.getContentType();
+        if (contentType != null) {
+            return StringUtils.startsWithIgnoreCase(contentType, MediaType.APPLICATION_JSON_VALUE);
+        }
+        return false;
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/utils/UnsignedMathGenerator.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/utils/UnsignedMathGenerator.java
new file mode 100644
index 0000000..a400cff
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/utils/UnsignedMathGenerator.java
@@ -0,0 +1,88 @@
+package org.dromara.common.web.utils;
+
+import cn.hutool.captcha.generator.CodeGenerator;
+import cn.hutool.core.math.Calculator;
+import cn.hutool.core.util.CharUtil;
+import cn.hutool.core.util.RandomUtil;
+import org.dromara.common.core.utils.StringUtils;
+
+import java.io.Serial;
+
+/**
+ * 鏃犵鍙疯绠楃敓鎴愬櫒
+ *
+ * @author Lion Li
+ */
+public class UnsignedMathGenerator implements CodeGenerator {
+
+    @Serial
+    private static final long serialVersionUID = -5514819971774091076L;
+
+    private static final String OPERATORS = "+-*";
+
+    /**
+     * 鍙備笌璁$畻鏁板瓧鏈�澶ч暱搴�
+     */
+    private final int numberLength;
+
+    /**
+     * 鏋勯��
+     */
+    public UnsignedMathGenerator() {
+        this(2);
+    }
+
+    /**
+     * 鏋勯��
+     *
+     * @param numberLength 鍙備笌璁$畻鏈�澶ф暟瀛椾綅鏁�
+     */
+    public UnsignedMathGenerator(int numberLength) {
+        this.numberLength = numberLength;
+    }
+
+    @Override
+    public String generate() {
+        final int limit = getLimit();
+        int a = RandomUtil.randomInt(limit);
+        int b = RandomUtil.randomInt(limit);
+        String max = Integer.toString(Math.max(a,b));
+        String min = Integer.toString(Math.min(a,b));
+        max = StringUtils.rightPad(max, this.numberLength, CharUtil.SPACE);
+        min = StringUtils.rightPad(min, this.numberLength, CharUtil.SPACE);
+
+        return max + RandomUtil.randomChar(OPERATORS) + min + '=';
+    }
+
+    @Override
+    public boolean verify(String code, String userInputCode) {
+        int result;
+        try {
+            result = Integer.parseInt(userInputCode);
+        } catch (NumberFormatException e) {
+            // 鐢ㄦ埛杈撳叆闈炴暟瀛�
+            return false;
+        }
+
+        final int calculateResult = (int) Calculator.conversion(code);
+        return result == calculateResult;
+    }
+
+    /**
+     * 鑾峰彇楠岃瘉鐮侀暱搴�
+     *
+     * @return 楠岃瘉鐮侀暱搴�
+     */
+    public int getLength() {
+        return this.numberLength * 2 + 2;
+    }
+
+    /**
+     * 鏍规嵁闀垮害鑾峰彇鍙備笌璁$畻鏁板瓧鏈�澶у��
+     *
+     * @return 鏈�澶у��
+     */
+    private int getLimit() {
+        return Integer.parseInt("1" + StringUtils.repeat('0', this.numberLength));
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index cdf8c66..fc10a36 100644
--- a/ruoyi-common/ruoyi-common-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-common/ruoyi-common-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1,5 +1,5 @@
-com.ruoyi.common.web.config.CaptchaConfig
-com.ruoyi.common.web.config.FilterConfig
-com.ruoyi.common.web.config.I18nConfig
-com.ruoyi.common.web.config.ResourcesConfig
-com.ruoyi.common.web.config.UndertowConfig
+org.dromara.common.web.config.CaptchaConfig
+org.dromara.common.web.config.FilterConfig
+org.dromara.common.web.config.I18nConfig
+org.dromara.common.web.config.ResourcesConfig
+org.dromara.common.web.config.UndertowConfig
diff --git a/ruoyi-common/ruoyi-common-websocket/pom.xml b/ruoyi-common/ruoyi-common-websocket/pom.xml
index 21a5727..5b9fb37 100644
--- a/ruoyi-common/ruoyi-common-websocket/pom.xml
+++ b/ruoyi-common/ruoyi-common-websocket/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-common</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -18,19 +18,19 @@
 
     <dependencies>
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-core</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-redis</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-satoken</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-json</artifactId>
         </dependency>
         <dependency>
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/config/WebSocketConfig.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/config/WebSocketConfig.java
deleted file mode 100644
index 321c94c..0000000
--- a/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/config/WebSocketConfig.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package com.ruoyi.common.websocket.config;
-
-import cn.hutool.core.util.StrUtil;
-import com.ruoyi.common.websocket.config.properties.WebSocketProperties;
-import com.ruoyi.common.websocket.handler.PlusWebSocketHandler;
-import com.ruoyi.common.websocket.interceptor.PlusWebSocketInterceptor;
-import com.ruoyi.common.websocket.listener.WebSocketTopicListener;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.web.socket.WebSocketHandler;
-import org.springframework.web.socket.config.annotation.EnableWebSocket;
-import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
-import org.springframework.web.socket.server.HandshakeInterceptor;
-
-/**
- * WebSocket 閰嶇疆
- *
- * @author zendwang
- */
-@AutoConfiguration
-@ConditionalOnProperty(value = "websocket.enabled", havingValue = "true")
-@EnableConfigurationProperties(WebSocketProperties.class)
-@EnableWebSocket
-public class WebSocketConfig {
-
-    @Bean
-    public WebSocketConfigurer webSocketConfigurer(HandshakeInterceptor handshakeInterceptor,
-                                                   WebSocketHandler webSocketHandler,
-                                                   WebSocketProperties webSocketProperties) {
-        if (StrUtil.isBlank(webSocketProperties.getPath())) {
-            webSocketProperties.setPath("/websocket");
-        }
-
-        if (StrUtil.isBlank(webSocketProperties.getAllowedOrigins())) {
-            webSocketProperties.setAllowedOrigins("*");
-        }
-
-        return registry -> registry
-            .addHandler(webSocketHandler, webSocketProperties.getPath())
-            .addInterceptors(handshakeInterceptor)
-            .setAllowedOrigins(webSocketProperties.getAllowedOrigins());
-    }
-
-    @Bean
-    public HandshakeInterceptor handshakeInterceptor() {
-        return new PlusWebSocketInterceptor();
-    }
-
-    @Bean
-    public WebSocketHandler webSocketHandler() {
-        return new PlusWebSocketHandler();
-    }
-
-    @Bean
-    public WebSocketTopicListener topicListener() {
-        return new WebSocketTopicListener();
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/config/properties/WebSocketProperties.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/config/properties/WebSocketProperties.java
deleted file mode 100644
index 97ce992..0000000
--- a/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/config/properties/WebSocketProperties.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.ruoyi.common.websocket.config.properties;
-
-import lombok.Data;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-/**
- * WebSocket 閰嶇疆椤�
- *
- * @author zendwang
- */
-@ConfigurationProperties("websocket")
-@Data
-public class WebSocketProperties {
-
-    private Boolean enabled;
-
-    /**
-     * 璺緞
-     */
-    private String path;
-
-    /**
-     *  璁剧疆璁块棶婧愬湴鍧�
-     */
-    private String allowedOrigins;
-}
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/constant/WebSocketConstants.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/constant/WebSocketConstants.java
deleted file mode 100644
index 8c88832..0000000
--- a/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/constant/WebSocketConstants.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.ruoyi.common.websocket.constant;
-
-/**
- * websocket鐨勫父閲忛厤缃�
- *
- * @author zendwang
- */
-public interface WebSocketConstants {
-    /**
-     * websocketSession涓殑鍙傛暟鐨刱ey
-     */
-    String LOGIN_USER_KEY = "loginUser";
-
-    /**
-     * 璁㈤槄鐨勯閬�
-     */
-    String WEB_SOCKET_TOPIC = "global:websocket";
-
-    /**
-     * 鍓嶇蹇冭烦妫�鏌ョ殑鍛戒护
-     */
-    String PING = "ping";
-
-    /**
-     * 鏈嶅姟绔績璺虫仮澶嶇殑瀛楃涓�
-     */
-    String PONG = "pong";
-}
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/dto/WebSocketMessageDto.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/dto/WebSocketMessageDto.java
deleted file mode 100644
index 0b38ed1..0000000
--- a/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/dto/WebSocketMessageDto.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.ruoyi.common.websocket.dto;
-
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * 娑堟伅鐨刣to
- *
- * @author zendwang
- */
-@Data
-public class WebSocketMessageDto implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 闇�瑕佹帹閫佸埌鐨剆ession key 鍒楄〃
-     */
-    private List<Long> sessionKeys;
-
-    /**
-     * 闇�瑕佸彂閫佺殑娑堟伅
-     */
-    private String message;
-}
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/handler/PlusWebSocketHandler.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/handler/PlusWebSocketHandler.java
deleted file mode 100644
index 73717fa..0000000
--- a/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/handler/PlusWebSocketHandler.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package com.ruoyi.common.websocket.handler;
-
-import com.ruoyi.common.core.domain.model.LoginUser;
-import com.ruoyi.common.websocket.dto.WebSocketMessageDto;
-import com.ruoyi.common.websocket.holder.WebSocketSessionHolder;
-import com.ruoyi.common.websocket.utils.WebSocketUtils;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.web.socket.*;
-import org.springframework.web.socket.handler.AbstractWebSocketHandler;
-
-import java.util.List;
-
-import static com.ruoyi.common.websocket.constant.WebSocketConstants.LOGIN_USER_KEY;
-
-/**
- * WebSocketHandler 瀹炵幇绫�
- *
- * @author zendwang
- */
-@Slf4j
-public class PlusWebSocketHandler extends AbstractWebSocketHandler {
-
-    /**
-     * 杩炴帴鎴愬姛鍚�
-     */
-    @Override
-    public void afterConnectionEstablished(WebSocketSession session) {
-        LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY);
-        WebSocketSessionHolder.addSession(loginUser.getUserId(), session);
-        log.info("[connect] sessionId: {},userId:{},userType:{}", session.getId(), loginUser.getUserId(), loginUser.getUserType());
-    }
-
-    /**
-     * 澶勭悊鍙戦�佹潵鐨勬枃鏈秷鎭�
-     *
-     * @param session
-     * @param message
-     * @throws Exception
-     */
-    @Override
-    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
-        LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY);
-        log.info("PlusWebSocketHandler, 杩炴帴锛�" + session.getId() + "锛屽凡鏀跺埌娑堟伅:" + message.getPayload());
-        List<Long> userIds = List.of(loginUser.getUserId());
-        WebSocketMessageDto webSocketMessageDto = new WebSocketMessageDto();
-        webSocketMessageDto.setSessionKeys(userIds);
-        webSocketMessageDto.setMessage(message.getPayload());
-        WebSocketUtils.publishMessage(webSocketMessageDto);
-    }
-
-    @Override
-    protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {
-        super.handleBinaryMessage(session, message);
-    }
-
-    /**
-     * 蹇冭烦鐩戞祴鐨勫洖澶�
-     *
-     * @param session
-     * @param message
-     * @throws Exception
-     */
-    @Override
-    protected void handlePongMessage(WebSocketSession session, PongMessage message) throws Exception {
-        WebSocketUtils.sendPongMessage(session);
-    }
-
-    /**
-     * 杩炴帴鍑洪敊鏃�
-     *
-     * @param session
-     * @param exception
-     * @throws Exception
-     */
-    @Override
-    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
-        log.error("[transport error] sessionId: {} , exception:{}", session.getId(), exception.getMessage());
-    }
-
-    /**
-     * 杩炴帴鍏抽棴鍚�
-     *
-     * @param session
-     * @param status
-     */
-    @Override
-    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
-        LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY);
-        WebSocketSessionHolder.removeSession(loginUser.getUserId());
-        log.info("[disconnect] sessionId: {},userId:{},userType:{}", session.getId(), loginUser.getUserId(), loginUser.getUserType());
-    }
-
-    /**
-     * 鏄惁鏀寔鍒嗙墖娑堟伅
-     *
-     * @return
-     */
-    @Override
-    public boolean supportsPartialMessages() {
-        return false;
-    }
-
-}
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/holder/WebSocketSessionHolder.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/holder/WebSocketSessionHolder.java
deleted file mode 100644
index facc84d..0000000
--- a/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/holder/WebSocketSessionHolder.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.ruoyi.common.websocket.holder;
-
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import org.springframework.web.socket.WebSocketSession;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * WebSocketSession 鐢ㄤ簬淇濆瓨褰撳墠鎵�鏈夊湪绾跨殑浼氳瘽淇℃伅
- *
- * @author zendwang
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class WebSocketSessionHolder {
-
-    private static final Map<Long, WebSocketSession> USER_SESSION_MAP = new ConcurrentHashMap<>();
-
-    public static void addSession(Long sessionKey, WebSocketSession session) {
-        USER_SESSION_MAP.put(sessionKey, session);
-    }
-
-    public static void removeSession(Long sessionKey) {
-        if (USER_SESSION_MAP.containsKey(sessionKey)) {
-            USER_SESSION_MAP.remove(sessionKey);
-        }
-    }
-
-    public static WebSocketSession getSessions(Long sessionKey) {
-        return USER_SESSION_MAP.get(sessionKey);
-    }
-
-    public static Boolean existSession(Long sessionKey) {
-        return USER_SESSION_MAP.containsKey(sessionKey);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/interceptor/PlusWebSocketInterceptor.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/interceptor/PlusWebSocketInterceptor.java
deleted file mode 100644
index bbb1d48..0000000
--- a/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/interceptor/PlusWebSocketInterceptor.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.ruoyi.common.websocket.interceptor;
-
-import com.ruoyi.common.core.domain.model.LoginUser;
-import com.ruoyi.common.satoken.utils.LoginHelper;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.http.server.ServerHttpRequest;
-import org.springframework.http.server.ServerHttpResponse;
-import org.springframework.web.socket.WebSocketHandler;
-import org.springframework.web.socket.server.HandshakeInterceptor;
-
-import java.util.Map;
-
-import static com.ruoyi.common.websocket.constant.WebSocketConstants.LOGIN_USER_KEY;
-
-/**
- * WebSocket鎻℃墜璇锋眰鐨勬嫤鎴櫒
- *
- * @author zendwang
- */
-@Slf4j
-public class PlusWebSocketInterceptor implements HandshakeInterceptor {
-
-    /**
-     * 鎻℃墜鍓�
-     *
-     * @param request    request
-     * @param response   response
-     * @param wsHandler  wsHandler
-     * @param attributes attributes
-     * @return 鏄惁鎻℃墜鎴愬姛
-     */
-    @Override
-    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) {
-        LoginUser loginUser = LoginHelper.getLoginUser();
-        attributes.put(LOGIN_USER_KEY, loginUser);
-        return true;
-    }
-
-    /**
-     * 鎻℃墜鍚�
-     *
-     * @param request   request
-     * @param response  response
-     * @param wsHandler wsHandler
-     * @param exception 寮傚父
-     */
-    @Override
-    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
-
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/listener/WebSocketTopicListener.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/listener/WebSocketTopicListener.java
deleted file mode 100644
index cdc141f..0000000
--- a/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/listener/WebSocketTopicListener.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.ruoyi.common.websocket.listener;
-
-import cn.hutool.core.collection.CollUtil;
-import com.ruoyi.common.websocket.holder.WebSocketSessionHolder;
-import com.ruoyi.common.websocket.utils.WebSocketUtils;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.boot.ApplicationArguments;
-import org.springframework.boot.ApplicationRunner;
-import org.springframework.core.Ordered;
-
-/**
- * WebSocket 涓婚璁㈤槄鐩戝惉鍣�
- *
- * @author zendwang
- */
-@Slf4j
-public class WebSocketTopicListener implements ApplicationRunner, Ordered {
-
-    @Override
-    public void run(ApplicationArguments args) throws Exception {
-        WebSocketUtils.subscribeMessage((message) -> {
-            log.info("WebSocket涓婚璁㈤槄鏀跺埌娑堟伅session keys={}  message={}锛�", message.getSessionKeys(), message.getMessage());
-            if (CollUtil.isNotEmpty(message.getSessionKeys())) {
-                message.getSessionKeys().forEach(key -> {
-                    if (WebSocketSessionHolder.existSession(key)) {
-                        WebSocketUtils.sendMessage(key, message.getMessage());
-                    }
-                });
-            }
-        });
-        log.info("鍒濆鍖朩ebSocket涓婚璁㈤槄鐩戝惉鍣ㄦ垚鍔�");
-    }
-
-    @Override
-    public int getOrder() {
-        return -1;
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/utils/WebSocketUtils.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/utils/WebSocketUtils.java
deleted file mode 100644
index b4f181e..0000000
--- a/ruoyi-common/ruoyi-common-websocket/src/main/java/com/ruoyi/common/websocket/utils/WebSocketUtils.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package com.ruoyi.common.websocket.utils;
-
-import cn.hutool.core.collection.CollUtil;
-import com.ruoyi.common.core.domain.model.LoginUser;
-import com.ruoyi.common.redis.utils.RedisUtils;
-import com.ruoyi.common.websocket.dto.WebSocketMessageDto;
-import com.ruoyi.common.websocket.holder.WebSocketSessionHolder;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.web.socket.PongMessage;
-import org.springframework.web.socket.TextMessage;
-import org.springframework.web.socket.WebSocketMessage;
-import org.springframework.web.socket.WebSocketSession;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Consumer;
-
-import static com.ruoyi.common.websocket.constant.WebSocketConstants.LOGIN_USER_KEY;
-import static com.ruoyi.common.websocket.constant.WebSocketConstants.WEB_SOCKET_TOPIC;
-
-/**
- * 宸ュ叿绫�
- *
- * @author zendwang
- */
-@Slf4j
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class WebSocketUtils {
-
-    /**
-     * 鍙戦�佹秷鎭�
-     *
-     * @param sessionKey session涓婚敭 涓�鑸负鐢ㄦ埛id
-     * @param message    娑堟伅鏂囨湰
-     */
-    public static void sendMessage(Long sessionKey, String message) {
-        WebSocketSession session = WebSocketSessionHolder.getSessions(sessionKey);
-        sendMessage(session, message);
-    }
-
-    /**
-     * 璁㈤槄娑堟伅
-     *
-     * @param consumer 鑷畾涔夊鐞�
-     */
-    public static void subscribeMessage(Consumer<WebSocketMessageDto> consumer) {
-        RedisUtils.subscribe(WEB_SOCKET_TOPIC, WebSocketMessageDto.class, consumer);
-    }
-
-    /**
-     * 鍙戝竷璁㈤槄鐨勬秷鎭�
-     *
-     * @param webSocketMessage 娑堟伅瀵硅薄
-     */
-    public static void publishMessage(WebSocketMessageDto webSocketMessage) {
-        List<Long> unsentSessionKeys = new ArrayList<>();
-        // 褰撳墠鏈嶅姟鍐卻ession,鐩存帴鍙戦�佹秷鎭�
-        for (Long sessionKey : webSocketMessage.getSessionKeys()) {
-            if (WebSocketSessionHolder.existSession(sessionKey)) {
-                WebSocketUtils.sendMessage(sessionKey, webSocketMessage.getMessage());
-                continue;
-            }
-            unsentSessionKeys.add(sessionKey);
-        }
-        // 涓嶅湪褰撳墠鏈嶅姟鍐卻ession,鍙戝竷璁㈤槄娑堟伅
-        if (CollUtil.isNotEmpty(unsentSessionKeys)) {
-            WebSocketMessageDto broadcastMessage = new WebSocketMessageDto();
-            broadcastMessage.setMessage(webSocketMessage.getMessage());
-            broadcastMessage.setSessionKeys(unsentSessionKeys);
-            RedisUtils.publish(WEB_SOCKET_TOPIC, broadcastMessage, consumer -> {
-                log.info(" WebSocket鍙戦�佷富棰樿闃呮秷鎭痶opic:{} session keys:{} message:{}",
-                    WEB_SOCKET_TOPIC, unsentSessionKeys, webSocketMessage.getMessage());
-            });
-        }
-    }
-
-    public static void sendPongMessage(WebSocketSession session) {
-        sendMessage(session, new PongMessage());
-    }
-
-    public static void sendMessage(WebSocketSession session, String message) {
-        sendMessage(session, new TextMessage(message));
-    }
-
-    private static void sendMessage(WebSocketSession session, WebSocketMessage<?> message) {
-        if (session == null || !session.isOpen()) {
-            log.error("[send] session浼氳瘽宸茬粡鍏抽棴");
-        } else {
-            try {
-                // 鑾峰彇褰撳墠浼氳瘽涓殑鐢ㄦ埛
-                LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY);
-                session.sendMessage(message);
-                log.info("[send] sessionId: {},userId:{},userType:{},message:{}", session.getId(), loginUser.getUserId(), loginUser.getUserType(), message);
-            } catch (IOException e) {
-                log.error("[send] session({}) 鍙戦�佹秷鎭�({}) 寮傚父", session, message, e);
-            }
-        }
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/config/WebSocketConfig.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/config/WebSocketConfig.java
new file mode 100644
index 0000000..30d109e
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/config/WebSocketConfig.java
@@ -0,0 +1,60 @@
+package org.dromara.common.websocket.config;
+
+import cn.hutool.core.util.StrUtil;
+import org.dromara.common.websocket.config.properties.WebSocketProperties;
+import org.dromara.common.websocket.handler.PlusWebSocketHandler;
+import org.dromara.common.websocket.interceptor.PlusWebSocketInterceptor;
+import org.dromara.common.websocket.listener.WebSocketTopicListener;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.socket.WebSocketHandler;
+import org.springframework.web.socket.config.annotation.EnableWebSocket;
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
+import org.springframework.web.socket.server.HandshakeInterceptor;
+
+/**
+ * WebSocket 閰嶇疆
+ *
+ * @author zendwang
+ */
+@AutoConfiguration
+@ConditionalOnProperty(value = "websocket.enabled", havingValue = "true")
+@EnableConfigurationProperties(WebSocketProperties.class)
+@EnableWebSocket
+public class WebSocketConfig {
+
+    @Bean
+    public WebSocketConfigurer webSocketConfigurer(HandshakeInterceptor handshakeInterceptor,
+                                                   WebSocketHandler webSocketHandler,
+                                                   WebSocketProperties webSocketProperties) {
+        if (StrUtil.isBlank(webSocketProperties.getPath())) {
+            webSocketProperties.setPath("/websocket");
+        }
+
+        if (StrUtil.isBlank(webSocketProperties.getAllowedOrigins())) {
+            webSocketProperties.setAllowedOrigins("*");
+        }
+
+        return registry -> registry
+            .addHandler(webSocketHandler, webSocketProperties.getPath())
+            .addInterceptors(handshakeInterceptor)
+            .setAllowedOrigins(webSocketProperties.getAllowedOrigins());
+    }
+
+    @Bean
+    public HandshakeInterceptor handshakeInterceptor() {
+        return new PlusWebSocketInterceptor();
+    }
+
+    @Bean
+    public WebSocketHandler webSocketHandler() {
+        return new PlusWebSocketHandler();
+    }
+
+    @Bean
+    public WebSocketTopicListener topicListener() {
+        return new WebSocketTopicListener();
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/config/properties/WebSocketProperties.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/config/properties/WebSocketProperties.java
new file mode 100644
index 0000000..d629fe5
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/config/properties/WebSocketProperties.java
@@ -0,0 +1,26 @@
+package org.dromara.common.websocket.config.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * WebSocket 閰嶇疆椤�
+ *
+ * @author zendwang
+ */
+@ConfigurationProperties("websocket")
+@Data
+public class WebSocketProperties {
+
+    private Boolean enabled;
+
+    /**
+     * 璺緞
+     */
+    private String path;
+
+    /**
+     *  璁剧疆璁块棶婧愬湴鍧�
+     */
+    private String allowedOrigins;
+}
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/constant/WebSocketConstants.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/constant/WebSocketConstants.java
new file mode 100644
index 0000000..54eb447
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/constant/WebSocketConstants.java
@@ -0,0 +1,28 @@
+package org.dromara.common.websocket.constant;
+
+/**
+ * websocket鐨勫父閲忛厤缃�
+ *
+ * @author zendwang
+ */
+public interface WebSocketConstants {
+    /**
+     * websocketSession涓殑鍙傛暟鐨刱ey
+     */
+    String LOGIN_USER_KEY = "loginUser";
+
+    /**
+     * 璁㈤槄鐨勯閬�
+     */
+    String WEB_SOCKET_TOPIC = "global:websocket";
+
+    /**
+     * 鍓嶇蹇冭烦妫�鏌ョ殑鍛戒护
+     */
+    String PING = "ping";
+
+    /**
+     * 鏈嶅姟绔績璺虫仮澶嶇殑瀛楃涓�
+     */
+    String PONG = "pong";
+}
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/dto/WebSocketMessageDto.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/dto/WebSocketMessageDto.java
new file mode 100644
index 0000000..e2d4456
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/dto/WebSocketMessageDto.java
@@ -0,0 +1,29 @@
+package org.dromara.common.websocket.dto;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 娑堟伅鐨刣to
+ *
+ * @author zendwang
+ */
+@Data
+public class WebSocketMessageDto implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 闇�瑕佹帹閫佸埌鐨剆ession key 鍒楄〃
+     */
+    private List<Long> sessionKeys;
+
+    /**
+     * 闇�瑕佸彂閫佺殑娑堟伅
+     */
+    private String message;
+}
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/handler/PlusWebSocketHandler.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/handler/PlusWebSocketHandler.java
new file mode 100644
index 0000000..0400b56
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/handler/PlusWebSocketHandler.java
@@ -0,0 +1,103 @@
+package org.dromara.common.websocket.handler;
+
+import org.dromara.common.core.domain.model.LoginUser;
+import org.dromara.common.websocket.dto.WebSocketMessageDto;
+import org.dromara.common.websocket.holder.WebSocketSessionHolder;
+import org.dromara.common.websocket.utils.WebSocketUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.socket.*;
+import org.springframework.web.socket.handler.AbstractWebSocketHandler;
+
+import java.util.List;
+
+import static org.dromara.common.websocket.constant.WebSocketConstants.LOGIN_USER_KEY;
+
+/**
+ * WebSocketHandler 瀹炵幇绫�
+ *
+ * @author zendwang
+ */
+@Slf4j
+public class PlusWebSocketHandler extends AbstractWebSocketHandler {
+
+    /**
+     * 杩炴帴鎴愬姛鍚�
+     */
+    @Override
+    public void afterConnectionEstablished(WebSocketSession session) {
+        LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY);
+        WebSocketSessionHolder.addSession(loginUser.getUserId(), session);
+        log.info("[connect] sessionId: {},userId:{},userType:{}", session.getId(), loginUser.getUserId(), loginUser.getUserType());
+    }
+
+    /**
+     * 澶勭悊鍙戦�佹潵鐨勬枃鏈秷鎭�
+     *
+     * @param session
+     * @param message
+     * @throws Exception
+     */
+    @Override
+    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
+        LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY);
+        log.info("PlusWebSocketHandler, 杩炴帴锛�" + session.getId() + "锛屽凡鏀跺埌娑堟伅:" + message.getPayload());
+        List<Long> userIds = List.of(loginUser.getUserId());
+        WebSocketMessageDto webSocketMessageDto = new WebSocketMessageDto();
+        webSocketMessageDto.setSessionKeys(userIds);
+        webSocketMessageDto.setMessage(message.getPayload());
+        WebSocketUtils.publishMessage(webSocketMessageDto);
+    }
+
+    @Override
+    protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {
+        super.handleBinaryMessage(session, message);
+    }
+
+    /**
+     * 蹇冭烦鐩戞祴鐨勫洖澶�
+     *
+     * @param session
+     * @param message
+     * @throws Exception
+     */
+    @Override
+    protected void handlePongMessage(WebSocketSession session, PongMessage message) throws Exception {
+        WebSocketUtils.sendPongMessage(session);
+    }
+
+    /**
+     * 杩炴帴鍑洪敊鏃�
+     *
+     * @param session
+     * @param exception
+     * @throws Exception
+     */
+    @Override
+    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
+        log.error("[transport error] sessionId: {} , exception:{}", session.getId(), exception.getMessage());
+    }
+
+    /**
+     * 杩炴帴鍏抽棴鍚�
+     *
+     * @param session
+     * @param status
+     */
+    @Override
+    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
+        LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY);
+        WebSocketSessionHolder.removeSession(loginUser.getUserId());
+        log.info("[disconnect] sessionId: {},userId:{},userType:{}", session.getId(), loginUser.getUserId(), loginUser.getUserType());
+    }
+
+    /**
+     * 鏄惁鏀寔鍒嗙墖娑堟伅
+     *
+     * @return
+     */
+    @Override
+    public boolean supportsPartialMessages() {
+        return false;
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/holder/WebSocketSessionHolder.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/holder/WebSocketSessionHolder.java
new file mode 100644
index 0000000..9b93193
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/holder/WebSocketSessionHolder.java
@@ -0,0 +1,37 @@
+package org.dromara.common.websocket.holder;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.springframework.web.socket.WebSocketSession;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * WebSocketSession 鐢ㄤ簬淇濆瓨褰撳墠鎵�鏈夊湪绾跨殑浼氳瘽淇℃伅
+ *
+ * @author zendwang
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class WebSocketSessionHolder {
+
+    private static final Map<Long, WebSocketSession> USER_SESSION_MAP = new ConcurrentHashMap<>();
+
+    public static void addSession(Long sessionKey, WebSocketSession session) {
+        USER_SESSION_MAP.put(sessionKey, session);
+    }
+
+    public static void removeSession(Long sessionKey) {
+        if (USER_SESSION_MAP.containsKey(sessionKey)) {
+            USER_SESSION_MAP.remove(sessionKey);
+        }
+    }
+
+    public static WebSocketSession getSessions(Long sessionKey) {
+        return USER_SESSION_MAP.get(sessionKey);
+    }
+
+    public static Boolean existSession(Long sessionKey) {
+        return USER_SESSION_MAP.containsKey(sessionKey);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/interceptor/PlusWebSocketInterceptor.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/interceptor/PlusWebSocketInterceptor.java
new file mode 100644
index 0000000..1dc4120
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/interceptor/PlusWebSocketInterceptor.java
@@ -0,0 +1,51 @@
+package org.dromara.common.websocket.interceptor;
+
+import org.dromara.common.core.domain.model.LoginUser;
+import org.dromara.common.satoken.utils.LoginHelper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.web.socket.WebSocketHandler;
+import org.springframework.web.socket.server.HandshakeInterceptor;
+
+import java.util.Map;
+
+import static org.dromara.common.websocket.constant.WebSocketConstants.LOGIN_USER_KEY;
+
+/**
+ * WebSocket鎻℃墜璇锋眰鐨勬嫤鎴櫒
+ *
+ * @author zendwang
+ */
+@Slf4j
+public class PlusWebSocketInterceptor implements HandshakeInterceptor {
+
+    /**
+     * 鎻℃墜鍓�
+     *
+     * @param request    request
+     * @param response   response
+     * @param wsHandler  wsHandler
+     * @param attributes attributes
+     * @return 鏄惁鎻℃墜鎴愬姛
+     */
+    @Override
+    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) {
+        LoginUser loginUser = LoginHelper.getLoginUser();
+        attributes.put(LOGIN_USER_KEY, loginUser);
+        return true;
+    }
+
+    /**
+     * 鎻℃墜鍚�
+     *
+     * @param request   request
+     * @param response  response
+     * @param wsHandler wsHandler
+     * @param exception 寮傚父
+     */
+    @Override
+    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
+
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/listener/WebSocketTopicListener.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/listener/WebSocketTopicListener.java
new file mode 100644
index 0000000..be385a7
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/listener/WebSocketTopicListener.java
@@ -0,0 +1,38 @@
+package org.dromara.common.websocket.listener;
+
+import cn.hutool.core.collection.CollUtil;
+import org.dromara.common.websocket.holder.WebSocketSessionHolder;
+import org.dromara.common.websocket.utils.WebSocketUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.core.Ordered;
+
+/**
+ * WebSocket 涓婚璁㈤槄鐩戝惉鍣�
+ *
+ * @author zendwang
+ */
+@Slf4j
+public class WebSocketTopicListener implements ApplicationRunner, Ordered {
+
+    @Override
+    public void run(ApplicationArguments args) throws Exception {
+        WebSocketUtils.subscribeMessage((message) -> {
+            log.info("WebSocket涓婚璁㈤槄鏀跺埌娑堟伅session keys={}  message={}锛�", message.getSessionKeys(), message.getMessage());
+            if (CollUtil.isNotEmpty(message.getSessionKeys())) {
+                message.getSessionKeys().forEach(key -> {
+                    if (WebSocketSessionHolder.existSession(key)) {
+                        WebSocketUtils.sendMessage(key, message.getMessage());
+                    }
+                });
+            }
+        });
+        log.info("鍒濆鍖朩ebSocket涓婚璁㈤槄鐩戝惉鍣ㄦ垚鍔�");
+    }
+
+    @Override
+    public int getOrder() {
+        return -1;
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java
new file mode 100644
index 0000000..c0bd2f3
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java
@@ -0,0 +1,102 @@
+package org.dromara.common.websocket.utils;
+
+import cn.hutool.core.collection.CollUtil;
+import org.dromara.common.core.domain.model.LoginUser;
+import org.dromara.common.redis.utils.RedisUtils;
+import org.dromara.common.websocket.dto.WebSocketMessageDto;
+import org.dromara.common.websocket.holder.WebSocketSessionHolder;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.socket.PongMessage;
+import org.springframework.web.socket.TextMessage;
+import org.springframework.web.socket.WebSocketMessage;
+import org.springframework.web.socket.WebSocketSession;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+
+import static org.dromara.common.websocket.constant.WebSocketConstants.LOGIN_USER_KEY;
+import static org.dromara.common.websocket.constant.WebSocketConstants.WEB_SOCKET_TOPIC;
+
+/**
+ * 宸ュ叿绫�
+ *
+ * @author zendwang
+ */
+@Slf4j
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class WebSocketUtils {
+
+    /**
+     * 鍙戦�佹秷鎭�
+     *
+     * @param sessionKey session涓婚敭 涓�鑸负鐢ㄦ埛id
+     * @param message    娑堟伅鏂囨湰
+     */
+    public static void sendMessage(Long sessionKey, String message) {
+        WebSocketSession session = WebSocketSessionHolder.getSessions(sessionKey);
+        sendMessage(session, message);
+    }
+
+    /**
+     * 璁㈤槄娑堟伅
+     *
+     * @param consumer 鑷畾涔夊鐞�
+     */
+    public static void subscribeMessage(Consumer<WebSocketMessageDto> consumer) {
+        RedisUtils.subscribe(WEB_SOCKET_TOPIC, WebSocketMessageDto.class, consumer);
+    }
+
+    /**
+     * 鍙戝竷璁㈤槄鐨勬秷鎭�
+     *
+     * @param webSocketMessage 娑堟伅瀵硅薄
+     */
+    public static void publishMessage(WebSocketMessageDto webSocketMessage) {
+        List<Long> unsentSessionKeys = new ArrayList<>();
+        // 褰撳墠鏈嶅姟鍐卻ession,鐩存帴鍙戦�佹秷鎭�
+        for (Long sessionKey : webSocketMessage.getSessionKeys()) {
+            if (WebSocketSessionHolder.existSession(sessionKey)) {
+                WebSocketUtils.sendMessage(sessionKey, webSocketMessage.getMessage());
+                continue;
+            }
+            unsentSessionKeys.add(sessionKey);
+        }
+        // 涓嶅湪褰撳墠鏈嶅姟鍐卻ession,鍙戝竷璁㈤槄娑堟伅
+        if (CollUtil.isNotEmpty(unsentSessionKeys)) {
+            WebSocketMessageDto broadcastMessage = new WebSocketMessageDto();
+            broadcastMessage.setMessage(webSocketMessage.getMessage());
+            broadcastMessage.setSessionKeys(unsentSessionKeys);
+            RedisUtils.publish(WEB_SOCKET_TOPIC, broadcastMessage, consumer -> {
+                log.info(" WebSocket鍙戦�佷富棰樿闃呮秷鎭痶opic:{} session keys:{} message:{}",
+                    WEB_SOCKET_TOPIC, unsentSessionKeys, webSocketMessage.getMessage());
+            });
+        }
+    }
+
+    public static void sendPongMessage(WebSocketSession session) {
+        sendMessage(session, new PongMessage());
+    }
+
+    public static void sendMessage(WebSocketSession session, String message) {
+        sendMessage(session, new TextMessage(message));
+    }
+
+    private static void sendMessage(WebSocketSession session, WebSocketMessage<?> message) {
+        if (session == null || !session.isOpen()) {
+            log.error("[send] session浼氳瘽宸茬粡鍏抽棴");
+        } else {
+            try {
+                // 鑾峰彇褰撳墠浼氳瘽涓殑鐢ㄦ埛
+                LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY);
+                session.sendMessage(message);
+                log.info("[send] sessionId: {},userId:{},userType:{},message:{}", session.getId(), loginUser.getUserId(), loginUser.getUserType(), message);
+            } catch (IOException e) {
+                log.error("[send] session({}) 鍙戦�佹秷鎭�({}) 寮傚父", session, message, e);
+            }
+        }
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-websocket/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index 3a059fa..c3a7305 100644
--- a/ruoyi-common/ruoyi-common-websocket/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-common/ruoyi-common-websocket/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +1 @@
-com.ruoyi.common.websocket.config.WebSocketConfig
+org.dromara.common.websocket.config.WebSocketConfig
diff --git a/ruoyi-extend/pom.xml b/ruoyi-extend/pom.xml
index f4c15ef..0b6b5d0 100644
--- a/ruoyi-extend/pom.xml
+++ b/ruoyi-extend/pom.xml
@@ -4,7 +4,7 @@
          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>
+        <groupId>org.dromara</groupId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
diff --git a/ruoyi-extend/ruoyi-monitor-admin/pom.xml b/ruoyi-extend/ruoyi-monitor-admin/pom.xml
index 1dd3f51..a839bc5 100644
--- a/ruoyi-extend/ruoyi-monitor-admin/pom.xml
+++ b/ruoyi-extend/ruoyi-monitor-admin/pom.xml
@@ -4,7 +4,7 @@
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <parent>
         <artifactId>ruoyi-extend</artifactId>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/MonitorAdminApplication.java b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/MonitorAdminApplication.java
deleted file mode 100644
index d4f038c..0000000
--- a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/MonitorAdminApplication.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.ruoyi.monitor.admin;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-/**
- * Admin 鐩戞帶鍚姩绋嬪簭
- *
- * @author Lion Li
- */
-@SpringBootApplication
-public class MonitorAdminApplication {
-
-    public static void main(String[] args) {
-        SpringApplication.run(MonitorAdminApplication.class, args);
-        System.out.println("Admin 鐩戞帶鍚姩鎴愬姛");
-    }
-
-}
diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/config/AdminServerConfig.java b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/config/AdminServerConfig.java
deleted file mode 100644
index e2a9c51..0000000
--- a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/config/AdminServerConfig.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.ruoyi.monitor.admin.config;
-
-import de.codecentric.boot.admin.server.config.EnableAdminServer;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration;
-import org.springframework.boot.task.TaskExecutorBuilder;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Lazy;
-import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
-
-import java.util.concurrent.Executor;
-
-/**
- * springboot-admin server閰嶇疆绫�
- *
- * @author Lion Li
- */
-@Configuration
-@EnableAdminServer
-public class AdminServerConfig {
-
-    @Lazy
-    @Bean(name = TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME)
-    @ConditionalOnMissingBean(Executor.class)
-    public ThreadPoolTaskExecutor applicationTaskExecutor(TaskExecutorBuilder builder) {
-        return builder.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
deleted file mode 100644
index 1115f6d..0000000
--- a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/config/SecurityConfig.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.ruoyi.monitor.admin.config;
-
-import de.codecentric.boot.admin.server.config.AdminServerProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
-
-/**
- * admin 鐩戞帶 瀹夊叏閰嶇疆
- *
- * @author Lion Li
- */
-@EnableWebSecurity
-@Configuration
-public class SecurityConfig {
-
-    private final String adminContextPath;
-
-    public SecurityConfig(AdminServerProperties adminServerProperties) {
-        this.adminContextPath = adminServerProperties.getContextPath();
-    }
-
-    @Bean
-    public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
-        SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
-        successHandler.setTargetUrlParameter("redirectTo");
-        successHandler.setDefaultTargetUrl(adminContextPath + "/");
-
-        return httpSecurity
-                .headers().frameOptions().disable()
-                .and().authorizeHttpRequests()
-                .requestMatchers(adminContextPath + "/assets/**"
-                    , adminContextPath + "/login"
-                    , "/actuator"
-                    , "/actuator/**"
-                ).permitAll()
-                .anyRequest().authenticated()
-                .and()
-                .formLogin().loginPage(adminContextPath + "/login")
-                .successHandler(successHandler).and()
-                .logout().logoutUrl(adminContextPath + "/logout")
-                .and()
-                .httpBasic().and()
-                .csrf()
-                .disable()
-                .build();
-    }
-
-}
diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/notifier/CustomNotifier.java b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/notifier/CustomNotifier.java
deleted file mode 100644
index 4d0a7a0..0000000
--- a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/notifier/CustomNotifier.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.ruoyi.monitor.admin.notifier;
-
-import de.codecentric.boot.admin.server.domain.entities.Instance;
-import de.codecentric.boot.admin.server.domain.entities.InstanceRepository;
-import de.codecentric.boot.admin.server.domain.events.InstanceEvent;
-import de.codecentric.boot.admin.server.domain.events.InstanceStatusChangedEvent;
-import de.codecentric.boot.admin.server.notify.AbstractEventNotifier;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-import reactor.core.publisher.Mono;
-
-/**
- * 鑷畾涔変簨浠堕�氱煡澶勭悊
- *
- * @author Lion Li
- */
-@Slf4j
-@Component
-public class CustomNotifier extends AbstractEventNotifier {
-
-    protected CustomNotifier(InstanceRepository repository) {
-        super(repository);
-    }
-
-    @Override
-    @SuppressWarnings("all")
-    protected Mono<Void> doNotify(InstanceEvent event, Instance instance) {
-        return Mono.fromRunnable(() -> {
-            // 瀹炰緥鐘舵�佹敼鍙樹簨浠�
-            if (event instanceof InstanceStatusChangedEvent) {
-                String registName = instance.getRegistration().getName();
-                String instanceId = event.getInstance().getValue();
-                String status = ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus();
-                log.info("Instance Status Change: [{}],[{}],[{}]", registName, instanceId, status);
-            }
-
-        });
-    }
-
-}
diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/MonitorAdminApplication.java b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/MonitorAdminApplication.java
new file mode 100644
index 0000000..0339ebb
--- /dev/null
+++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/MonitorAdminApplication.java
@@ -0,0 +1,19 @@
+package org.dromara.monitor.admin;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * Admin 鐩戞帶鍚姩绋嬪簭
+ *
+ * @author Lion Li
+ */
+@SpringBootApplication
+public class MonitorAdminApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(MonitorAdminApplication.class, args);
+        System.out.println("Admin 鐩戞帶鍚姩鎴愬姛");
+    }
+
+}
diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/config/AdminServerConfig.java b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/config/AdminServerConfig.java
new file mode 100644
index 0000000..1f70c75
--- /dev/null
+++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/config/AdminServerConfig.java
@@ -0,0 +1,31 @@
+package org.dromara.monitor.admin.config;
+
+import de.codecentric.boot.admin.server.config.EnableAdminServer;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration;
+import org.springframework.boot.task.TaskExecutorBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.Executor;
+
+/**
+ * springboot-admin server閰嶇疆绫�
+ *
+ * @author Lion Li
+ */
+@Configuration
+@EnableAdminServer
+public class AdminServerConfig {
+
+    @Lazy
+    @Bean(name = TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME)
+    @ConditionalOnMissingBean(Executor.class)
+    public ThreadPoolTaskExecutor applicationTaskExecutor(TaskExecutorBuilder builder) {
+        return builder.build();
+    }
+
+
+}
diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/config/SecurityConfig.java b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/config/SecurityConfig.java
new file mode 100644
index 0000000..4bd37ff
--- /dev/null
+++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/config/SecurityConfig.java
@@ -0,0 +1,52 @@
+package org.dromara.monitor.admin.config;
+
+import de.codecentric.boot.admin.server.config.AdminServerProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
+
+/**
+ * admin 鐩戞帶 瀹夊叏閰嶇疆
+ *
+ * @author Lion Li
+ */
+@EnableWebSecurity
+@Configuration
+public class SecurityConfig {
+
+    private final String adminContextPath;
+
+    public SecurityConfig(AdminServerProperties adminServerProperties) {
+        this.adminContextPath = adminServerProperties.getContextPath();
+    }
+
+    @Bean
+    public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
+        SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
+        successHandler.setTargetUrlParameter("redirectTo");
+        successHandler.setDefaultTargetUrl(adminContextPath + "/");
+
+        return httpSecurity
+                .headers().frameOptions().disable()
+                .and().authorizeHttpRequests()
+                .requestMatchers(adminContextPath + "/assets/**"
+                    , adminContextPath + "/login"
+                    , "/actuator"
+                    , "/actuator/**"
+                ).permitAll()
+                .anyRequest().authenticated()
+                .and()
+                .formLogin().loginPage(adminContextPath + "/login")
+                .successHandler(successHandler).and()
+                .logout().logoutUrl(adminContextPath + "/logout")
+                .and()
+                .httpBasic().and()
+                .csrf()
+                .disable()
+                .build();
+    }
+
+}
diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/notifier/CustomNotifier.java b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/notifier/CustomNotifier.java
new file mode 100644
index 0000000..477a598
--- /dev/null
+++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/notifier/CustomNotifier.java
@@ -0,0 +1,40 @@
+package org.dromara.monitor.admin.notifier;
+
+import de.codecentric.boot.admin.server.domain.entities.Instance;
+import de.codecentric.boot.admin.server.domain.entities.InstanceRepository;
+import de.codecentric.boot.admin.server.domain.events.InstanceEvent;
+import de.codecentric.boot.admin.server.domain.events.InstanceStatusChangedEvent;
+import de.codecentric.boot.admin.server.notify.AbstractEventNotifier;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import reactor.core.publisher.Mono;
+
+/**
+ * 鑷畾涔変簨浠堕�氱煡澶勭悊
+ *
+ * @author Lion Li
+ */
+@Slf4j
+@Component
+public class CustomNotifier extends AbstractEventNotifier {
+
+    protected CustomNotifier(InstanceRepository repository) {
+        super(repository);
+    }
+
+    @Override
+    @SuppressWarnings("all")
+    protected Mono<Void> doNotify(InstanceEvent event, Instance instance) {
+        return Mono.fromRunnable(() -> {
+            // 瀹炰緥鐘舵�佹敼鍙樹簨浠�
+            if (event instanceof InstanceStatusChangedEvent) {
+                String registName = instance.getRegistration().getName();
+                String instanceId = event.getInstance().getValue();
+                String status = ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus();
+                log.info("Instance Status Change: [{}],[{}],[{}]", registName, instanceId, status);
+            }
+
+        });
+    }
+
+}
diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/pom.xml b/ruoyi-extend/ruoyi-xxl-job-admin/pom.xml
index a8594c1..a95a04a 100644
--- a/ruoyi-extend/ruoyi-xxl-job-admin/pom.xml
+++ b/ruoyi-extend/ruoyi-xxl-job-admin/pom.xml
@@ -3,7 +3,7 @@
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <artifactId>ruoyi-extend</artifactId>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
diff --git a/ruoyi-modules/pom.xml b/ruoyi-modules/pom.xml
index 44deef0..1715577 100644
--- a/ruoyi-modules/pom.xml
+++ b/ruoyi-modules/pom.xml
@@ -4,7 +4,7 @@
          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>
+        <groupId>org.dromara</groupId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
diff --git a/ruoyi-modules/ruoyi-demo/pom.xml b/ruoyi-modules/ruoyi-demo/pom.xml
index e107149..a4cdbc5 100644
--- a/ruoyi-modules/ruoyi-demo/pom.xml
+++ b/ruoyi-modules/ruoyi-demo/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-modules</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -20,82 +20,82 @@
 
         <!-- 閫氱敤宸ュ叿-->
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-core</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-doc</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-sms</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-mail</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-redis</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-idempotent</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-mybatis</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-log</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-excel</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-web</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-ratelimiter</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-translation</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-sensitive</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-encrypt</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-tenant</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-websocket</artifactId>
         </dependency>
         <!-- 鐭俊 鐢ㄥ摢涓鍏ュ摢涓緷璧� -->
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/MailController.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/MailController.java
deleted file mode 100644
index 3d890ac..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/MailController.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.ruoyi.demo.controller;
-
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.mail.utils.MailUtils;
-import lombok.RequiredArgsConstructor;
-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 java.io.File;
-
-
-/**
- * 閭欢鍙戦�佹渚�
- *
- * @author Michelle.Chung
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/demo/mail")
-public class MailController {
-
-    /**
-     * 鍙戦�侀偖浠�
-     *
-     * @param to      鎺ユ敹浜�
-     * @param subject 鏍囬
-     * @param text    鍐呭
-     */
-    @GetMapping("/sendSimpleMessage")
-    public R<Void> sendSimpleMessage(String to, String subject, String text) {
-        MailUtils.sendText(to, subject, text);
-        return R.ok();
-    }
-
-    /**
-     * 鍙戦�侀偖浠讹紙甯﹂檮浠讹級
-     *
-     * @param to       鎺ユ敹浜�
-     * @param subject  鏍囬
-     * @param text     鍐呭
-     * @param filePath 闄勪欢璺緞
-     */
-    @GetMapping("/sendMessageWithAttachment")
-    public R<Void> sendMessageWithAttachment(String to, String subject, String text, String filePath) {
-        MailUtils.sendText(to, subject, text, new File(filePath));
-        return R.ok();
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java
deleted file mode 100644
index 20083ba..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package com.ruoyi.demo.controller;
-
-import com.ruoyi.common.core.constant.CacheNames;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.redis.utils.RedisUtils;
-import lombok.RequiredArgsConstructor;
-import org.springframework.cache.annotation.CacheEvict;
-import org.springframework.cache.annotation.CachePut;
-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;
-
-import java.time.Duration;
-
-/**
- * spring-cache 婕旂ず妗堜緥
- *
- * @author Lion Li
- */
-// 绫荤骇鍒� 缂撳瓨缁熶竴閰嶇疆
-//@CacheConfig(cacheNames = CacheNames.DEMO_CACHE)
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/demo/cache")
-public class RedisCacheController {
-
-    /**
-     * 娴嬭瘯 @Cacheable
-     * <p>
-     * 琛ㄧず杩欎釜鏂规硶鏈変簡缂撳瓨鐨勫姛鑳�,鏂规硶鐨勮繑鍥炲�间細琚紦瀛樹笅鏉�
-     * 涓嬩竴娆¤皟鐢ㄨ鏂规硶鍓�,浼氬幓妫�鏌ユ槸鍚︾紦瀛樹腑宸茬粡鏈夊��
-     * 濡傛灉鏈夊氨鐩存帴杩斿洖,涓嶈皟鐢ㄦ柟娉�
-     * 濡傛灉娌℃湁,灏辫皟鐢ㄦ柟娉�,鐒跺悗鎶婄粨鏋滅紦瀛樿捣鏉�
-     * 杩欎釜娉ㄨВ銆屼竴鑸敤鍦ㄦ煡璇㈡柟娉曚笂銆�
-     * <p>
-     * 閲嶇偣璇存槑: 缂撳瓨娉ㄨВ涓ヨ皑涓庡叾浠栫瓫閫夋暟鎹姛鑳戒竴璧蜂娇鐢�
-     * 渚嬪: 鏁版嵁鏉冮檺娉ㄨВ 浼氶�犳垚 缂撳瓨鍑荤┛ 涓� 鏁版嵁涓嶄竴鑷撮棶棰�
-     * <p>
-     * cacheNames 鍛藉悕瑙勫垯 鏌ョ湅 {@link CacheNames} 娉ㄩ噴 鏀寔澶氬弬鏁�
-     */
-    @Cacheable(cacheNames = "demo:cache#60s#10m#20", key = "#key", condition = "#key != null")
-    @GetMapping("/test1")
-    public R<String> test1(String key, String value) {
-        return R.ok("鎿嶄綔鎴愬姛", value);
-    }
-
-    /**
-     * 娴嬭瘯 @CachePut
-     * <p>
-     * 鍔犱簡@CachePut娉ㄨВ鐨勬柟娉�,浼氭妸鏂规硶鐨勮繑鍥炲�紁ut鍒扮紦瀛橀噷闈㈢紦瀛樿捣鏉�,渚涘叾瀹冨湴鏂逛娇鐢�
-     * 瀹冦�岄�氬父鐢ㄥ湪鏂板鎴栬�呭疄鏃舵洿鏂版柟娉曚笂銆�
-     * <p>
-     * cacheNames 鍛藉悕瑙勫垯 鏌ョ湅 {@link CacheNames} 娉ㄩ噴 鏀寔澶氬弬鏁�
-     */
-    @CachePut(cacheNames = CacheNames.DEMO_CACHE, key = "#key", condition = "#key != null")
-    @GetMapping("/test2")
-    public R<String> test2(String key, String value) {
-        return R.ok("鎿嶄綔鎴愬姛", value);
-    }
-
-    /**
-     * 娴嬭瘯 @CacheEvict
-     * <p>
-     * 浣跨敤浜咰acheEvict娉ㄨВ鐨勬柟娉�,浼氭竻绌烘寚瀹氱紦瀛�
-     * 銆屼竴鑸敤鍦ㄥ垹闄ょ殑鏂规硶涓娿��
-     * <p>
-     * cacheNames 鍛藉悕瑙勫垯 鏌ョ湅 {@link CacheNames} 娉ㄩ噴 鏀寔澶氬弬鏁�
-     */
-    @CacheEvict(cacheNames = CacheNames.DEMO_CACHE, key = "#key", condition = "#key != null")
-    @GetMapping("/test3")
-    public R<String> test3(String key, String value) {
-        return R.ok("鎿嶄綔鎴愬姛", value);
-    }
-
-    /**
-     * 娴嬭瘯璁剧疆杩囨湡鏃堕棿
-     * 鎵嬪姩璁剧疆杩囨湡鏃堕棿10绉�
-     * 11绉掑悗鑾峰彇 鍒ゆ柇鏄惁鐩哥瓑
-     */
-    @GetMapping("/test6")
-    public R<Boolean> test6(String key, String value) {
-        RedisUtils.setCacheObject(key, value);
-        boolean flag = RedisUtils.expire(key, Duration.ofSeconds(10));
-        System.out.println("***********" + flag);
-        try {
-            Thread.sleep(11 * 1000);
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-        }
-        Object obj = RedisUtils.getCacheObject(key);
-        return R.ok(value.equals(obj));
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java
deleted file mode 100644
index ebc923d..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package com.ruoyi.demo.controller;
-
-import com.baomidou.lock.LockInfo;
-import com.baomidou.lock.LockTemplate;
-import com.baomidou.lock.annotation.Lock4j;
-import com.baomidou.lock.executor.RedissonLockExecutor;
-import com.ruoyi.common.core.domain.R;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.time.LocalTime;
-
-
-/**
- * 娴嬭瘯鍒嗗竷寮忛攣鐨勬牱渚�
- *
- * @author shenxinquan
- */
-@Slf4j
-@RestController
-@RequestMapping("/demo/redisLock")
-public class RedisLockController {
-
-    @Autowired
-    private LockTemplate lockTemplate;
-
-    /**
-     * 娴嬭瘯lock4j 娉ㄨВ
-     */
-    @Lock4j(keys = {"#key"})
-    @GetMapping("/testLock4j")
-    public R<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 R.ok("鎿嶄綔鎴愬姛", value);
-    }
-
-    /**
-     * 娴嬭瘯lock4j 宸ュ叿
-     */
-    @GetMapping("/testLock4jLockTemplate")
-    public R<String> testLock4jLockTemplate(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 R.ok("鎿嶄綔鎴愬姛", value);
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisPubSubController.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisPubSubController.java
deleted file mode 100644
index 6ad80ce..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisPubSubController.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.ruoyi.demo.controller;
-
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.redis.utils.RedisUtils;
-import lombok.RequiredArgsConstructor;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * Redis 鍙戝竷璁㈤槄 婕旂ず妗堜緥
- *
- * @author Lion Li
- */
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/demo/redis/pubsub")
-public class RedisPubSubController {
-
-    /**
-     * 鍙戝竷娑堟伅
-     *
-     * @param key   閫氶亾Key
-     * @param value 鍙戦�佸唴瀹�
-     */
-    @GetMapping("/pub")
-    public R<Void> pub(String key, String value) {
-        RedisUtils.publish(key, value, consumer -> {
-            System.out.println("鍙戝竷閫氶亾 => " + key + ", 鍙戦�佸�� => " + value);
-        });
-        return R.ok("鎿嶄綔鎴愬姛");
-    }
-
-    /**
-     * 璁㈤槄娑堟伅
-     *
-     * @param key 閫氶亾Key
-     */
-    @GetMapping("/sub")
-    public R<Void> sub(String key) {
-        RedisUtils.subscribe(key, String.class, msg -> {
-            System.out.println("璁㈤槄閫氶亾 => " + key + ", 鎺ユ敹鍊� => " + msg);
-        });
-        return R.ok("鎿嶄綔鎴愬姛");
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisRateLimiterController.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisRateLimiterController.java
deleted file mode 100644
index 0fa861f..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisRateLimiterController.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.ruoyi.demo.controller;
-
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.ratelimiter.annotation.RateLimiter;
-import com.ruoyi.common.ratelimiter.enums.LimitType;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-
-/**
- * 娴嬭瘯鍒嗗竷寮忛檺娴佹牱渚�
- *
- * @author Lion Li
- */
-@Slf4j
-@RestController
-@RequestMapping("/demo/rateLimiter")
-public class RedisRateLimiterController {
-
-    /**
-     * 娴嬭瘯鍏ㄥ眬闄愭祦
-     * 鍏ㄥ眬褰卞搷
-     */
-    @RateLimiter(count = 2, time = 10)
-    @GetMapping("/test")
-    public R<String> test(String value) {
-        return R.ok("鎿嶄綔鎴愬姛", value);
-    }
-
-    /**
-     * 娴嬭瘯璇锋眰IP闄愭祦
-     * 鍚屼竴IP璇锋眰鍙楀奖鍝�
-     */
-    @RateLimiter(count = 2, time = 10, limitType = LimitType.IP)
-    @GetMapping("/testip")
-    public R<String> testip(String value) {
-        return R.ok("鎿嶄綔鎴愬姛", value);
-    }
-
-    /**
-     * 娴嬭瘯闆嗙兢瀹炰緥闄愭祦
-     * 鍚姩涓や釜鍚庣鏈嶅姟浜掍笉褰卞搷
-     */
-    @RateLimiter(count = 2, time = 10, limitType = LimitType.CLUSTER)
-    @GetMapping("/testcluster")
-    public R<String> testcluster(String value) {
-        return R.ok("鎿嶄綔鎴愬姛", value);
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/SmsController.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/SmsController.java
deleted file mode 100644
index bda9955..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/SmsController.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package com.ruoyi.demo.controller;
-
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.core.utils.SpringUtils;
-import com.ruoyi.common.sms.config.properties.SmsProperties;
-import com.ruoyi.common.sms.core.SmsTemplate;
-import lombok.RequiredArgsConstructor;
-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 java.util.HashMap;
-import java.util.Map;
-
-/**
- * 鐭俊婕旂ず妗堜緥
- * 璇峰厛闃呰鏂囨。 鍚﹀垯鏃犳硶浣跨敤
- *
- * @author Lion Li
- * @version 4.2.0
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/demo/sms")
-public class SmsController {
-
-    private final SmsProperties smsProperties;
-//    private final SmsTemplate smsTemplate; // 鍙互浣跨敤spring娉ㄥ叆
-//    private final AliyunSmsTemplate smsTemplate; // 涔熷彲浠ユ敞鍏ユ煇涓巶瀹剁殑妯℃澘宸ュ叿
-
-    /**
-     * 鍙戦�佺煭淇liyun
-     *
-     * @param phones     鐢佃瘽鍙�
-     * @param templateId 妯℃澘ID
-     */
-    @GetMapping("/sendAliyun")
-    public R<Object> sendAliyun(String phones, String templateId) {
-        if (!smsProperties.getEnabled()) {
-            return R.fail("褰撳墠绯荤粺娌℃湁寮�鍚煭淇″姛鑳斤紒");
-        }
-        if (!SpringUtils.containsBean("aliyunSmsTemplate")) {
-            return R.fail("闃块噷浜戜緷璧栨湭寮曞叆锛�");
-        }
-        SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class);
-        Map<String, String> map = new HashMap<>(1);
-        map.put("code", "1234");
-        Object send = smsTemplate.send(phones, templateId, map);
-        return R.ok(send);
-    }
-
-    /**
-     * 鍙戦�佺煭淇encent
-     *
-     * @param phones     鐢佃瘽鍙�
-     * @param templateId 妯℃澘ID
-     */
-    @GetMapping("/sendTencent")
-    public R<Object> sendTencent(String phones, String templateId) {
-        if (!smsProperties.getEnabled()) {
-            return R.fail("褰撳墠绯荤粺娌℃湁寮�鍚煭淇″姛鑳斤紒");
-        }
-        if (!SpringUtils.containsBean("tencentSmsTemplate")) {
-            return R.fail("鑵捐浜戜緷璧栨湭寮曞叆锛�");
-        }
-        SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class);
-        Map<String, String> map = new HashMap<>(1);
-//        map.put("2", "娴嬭瘯娴嬭瘯");
-        map.put("1", "1234");
-        Object send = smsTemplate.send(phones, templateId, map);
-        return R.ok(send);
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/Swagger3DemoController.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/Swagger3DemoController.java
deleted file mode 100644
index 0398b14..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/Swagger3DemoController.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.ruoyi.demo.controller;
-
-import com.ruoyi.common.core.domain.R;
-import org.springframework.http.MediaType;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestPart;
-import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.multipart.MultipartFile;
-
-/**
- * swagger3 鐢ㄦ硶绀轰緥
- *
- * @author Lion Li
- */
-@RestController
-@RequestMapping("/swagger/demo")
-public class Swagger3DemoController {
-
-    /**
-     * 涓婁紶璇锋眰
-     * 蹇呴』浣跨敤 @RequestPart 娉ㄨВ鏍囨敞涓烘枃浠�
-     *
-     * @param file 鏂囦欢
-     */
-    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
-    public R<String> upload(@RequestPart("file") MultipartFile file) {
-        return R.ok("鎿嶄綔鎴愬姛", file.getOriginalFilename());
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestBatchController.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestBatchController.java
deleted file mode 100644
index c94b8a3..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestBatchController.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package com.ruoyi.demo.controller;
-
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.demo.domain.TestDemo;
-import com.ruoyi.demo.mapper.TestDemoMapper;
-import lombok.RequiredArgsConstructor;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * 娴嬭瘯鎵归噺鏂规硶
- *
- * @author Lion Li
- * @date 2021-05-30
- */
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/demo/batch")
-public class TestBatchController extends BaseController {
-
-    /**
-     * 涓轰簡渚夸簬娴嬭瘯 鐩存帴寮曞叆mapper
-     */
-    private final TestDemoMapper testDemoMapper;
-
-    /**
-     * 鏂板鎵归噺鏂规硶 鍙畬缇庢浛浠� saveBatch 绉掔骇鎻掑叆涓婁竾鏁版嵁 (瀵筸ysql璐熻嵎杈冨ぇ)
-     * <p>
-     * 3.5.0 鐗堟湰 澧炲姞 rewriteBatchedStatements=true 鎵瑰鐞嗗弬鏁� 浣� MP 鍘熺敓鎵瑰鐞嗗彲浠ヨ揪鍒板悓鏍风殑閫熷害
-     */
-    @PostMapping("/add")
-//    @DS("slave")
-    public R<Void> add() {
-        List<TestDemo> list = new ArrayList<>();
-        for (int i = 0; i < 1000; i++) {
-            TestDemo testDemo = new TestDemo();
-            testDemo.setOrderNum(-1);
-            testDemo.setTestKey("鎵归噺鏂板");
-            testDemo.setValue("娴嬭瘯鏂板");
-            list.add(testDemo);
-        }
-        return toAjax(testDemoMapper.insertBatch(list));
-    }
-
-    /**
-     * 鏂板鎴栨洿鏂� 鍙畬缇庢浛浠� saveOrUpdateBatch 楂樻�ц兘
-     * <p>
-     * 3.5.0 鐗堟湰 澧炲姞 rewriteBatchedStatements=true 鎵瑰鐞嗗弬鏁� 浣� MP 鍘熺敓鎵瑰鐞嗗彲浠ヨ揪鍒板悓鏍风殑閫熷害
-     */
-    @PostMapping("/addOrUpdate")
-//    @DS("slave")
-    public R<Void> addOrUpdate() {
-        List<TestDemo> list = new ArrayList<>();
-        for (int i = 0; i < 1000; i++) {
-            TestDemo testDemo = new TestDemo();
-            testDemo.setOrderNum(-1);
-            testDemo.setTestKey("鎵归噺鏂板");
-            testDemo.setValue("娴嬭瘯鏂板");
-            list.add(testDemo);
-        }
-        testDemoMapper.insertBatch(list);
-        for (int i = 0; i < list.size(); i++) {
-            TestDemo testDemo = list.get(i);
-            testDemo.setTestKey("鎵归噺鏂板鎴栦慨鏀�");
-            testDemo.setValue("鎵归噺鏂板鎴栦慨鏀�");
-            if (i % 2 == 0) {
-                testDemo.setId(null);
-            }
-        }
-        return toAjax(testDemoMapper.insertOrUpdateBatch(list));
-    }
-
-    /**
-     * 鍒犻櫎鎵归噺鏂规硶
-     */
-    @DeleteMapping()
-//    @DS("slave")
-    public R<Void> remove() {
-        return toAjax(testDemoMapper.delete(new LambdaQueryWrapper<TestDemo>()
-            .eq(TestDemo::getOrderNum, -1L)));
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestDemoController.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestDemoController.java
deleted file mode 100644
index 2f6bc11..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestDemoController.java
+++ /dev/null
@@ -1,147 +0,0 @@
-package com.ruoyi.demo.controller;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.core.utils.MapstructUtils;
-import com.ruoyi.common.core.utils.ValidatorUtils;
-import com.ruoyi.common.core.validate.AddGroup;
-import com.ruoyi.common.core.validate.EditGroup;
-import com.ruoyi.common.core.validate.QueryGroup;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.common.idempotent.annotation.RepeatSubmit;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.excel.core.ExcelResult;
-import com.ruoyi.common.excel.utils.ExcelUtil;
-import com.ruoyi.common.log.annotation.Log;
-import com.ruoyi.common.log.enums.BusinessType;
-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 lombok.RequiredArgsConstructor;
-import org.springframework.http.MediaType;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
-
-import jakarta.servlet.http.HttpServletResponse;
-import jakarta.validation.constraints.NotEmpty;
-import jakarta.validation.constraints.NotNull;
-
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-
-/**
- * 娴嬭瘯鍗曡〃Controller
- *
- * @author Lion Li
- * @date 2021-07-26
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/demo/demo")
-public class TestDemoController extends BaseController {
-
-    private final ITestDemoService testDemoService;
-
-    /**
-     * 鏌ヨ娴嬭瘯鍗曡〃鍒楄〃
-     */
-    @SaCheckPermission("demo:demo:list")
-    @GetMapping("/list")
-    public TableDataInfo<TestDemoVo> list(@Validated(QueryGroup.class) TestDemoBo bo, PageQuery pageQuery) {
-        return testDemoService.queryPageList(bo, pageQuery);
-    }
-
-    /**
-     * 鑷畾涔夊垎椤垫煡璇�
-     */
-    @SaCheckPermission("demo:demo:list")
-    @GetMapping("/page")
-    public TableDataInfo<TestDemoVo> page(@Validated(QueryGroup.class) TestDemoBo bo, PageQuery pageQuery) {
-        return testDemoService.customPageList(bo, pageQuery);
-    }
-
-    /**
-     * 瀵煎叆鏁版嵁
-     *
-     * @param file 瀵煎叆鏂囦欢
-     */
-    @Log(title = "娴嬭瘯鍗曡〃", businessType = BusinessType.IMPORT)
-    @SaCheckPermission("demo:demo:import")
-    @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
-    public R<Void> importData(@RequestPart("file") MultipartFile file) throws Exception {
-        ExcelResult<TestDemoImportVo> excelResult = ExcelUtil.importExcel(file.getInputStream(), TestDemoImportVo.class, true);
-        List<TestDemo> list = MapstructUtils.convert(excelResult.getList(), TestDemo.class);
-        testDemoService.saveBatch(list);
-        return R.ok(excelResult.getAnalysis());
-    }
-
-    /**
-     * 瀵煎嚭娴嬭瘯鍗曡〃鍒楄〃
-     */
-    @SaCheckPermission("demo:demo:export")
-    @Log(title = "娴嬭瘯鍗曡〃", businessType = BusinessType.EXPORT)
-    @PostMapping("/export")
-    public void export(@Validated TestDemoBo bo, HttpServletResponse response) {
-        List<TestDemoVo> list = testDemoService.queryList(bo);
-        // 娴嬭瘯闆姳id瀵煎嚭
-//        for (TestDemoVo vo : list) {
-//            vo.setId(1234567891234567893L);
-//        }
-        ExcelUtil.exportExcel(list, "娴嬭瘯鍗曡〃", TestDemoVo.class, response);
-    }
-
-    /**
-     * 鑾峰彇娴嬭瘯鍗曡〃璇︾粏淇℃伅
-     *
-     * @param id 娴嬭瘯ID
-     */
-    @SaCheckPermission("demo:demo:query")
-    @GetMapping("/{id}")
-    public R<TestDemoVo> getInfo(@NotNull(message = "涓婚敭涓嶈兘涓虹┖")
-                                 @PathVariable("id") Long id) {
-        return R.ok(testDemoService.queryById(id));
-    }
-
-    /**
-     * 鏂板娴嬭瘯鍗曡〃
-     */
-    @SaCheckPermission("demo:demo:add")
-    @Log(title = "娴嬭瘯鍗曡〃", businessType = BusinessType.INSERT)
-    @RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS, message = "{repeat.submit.message}")
-    @PostMapping()
-    public R<Void> add(@RequestBody TestDemoBo bo) {
-        // 浣跨敤鏍¢獙宸ュ叿瀵规爣 @Validated(AddGroup.class) 娉ㄨВ
-        // 鐢ㄤ簬鍦ㄩ潪 Controller 鐨勫湴鏂规牎楠屽璞�
-        ValidatorUtils.validate(bo, AddGroup.class);
-        return toAjax(testDemoService.insertByBo(bo));
-    }
-
-    /**
-     * 淇敼娴嬭瘯鍗曡〃
-     */
-    @SaCheckPermission("demo:demo:edit")
-    @Log(title = "娴嬭瘯鍗曡〃", businessType = BusinessType.UPDATE)
-    @RepeatSubmit
-    @PutMapping()
-    public R<Void> edit(@Validated(EditGroup.class) @RequestBody TestDemoBo bo) {
-        return toAjax(testDemoService.updateByBo(bo));
-    }
-
-    /**
-     * 鍒犻櫎娴嬭瘯鍗曡〃
-     *
-     * @param ids 娴嬭瘯ID涓�
-     */
-    @SaCheckPermission("demo:demo:remove")
-    @Log(title = "娴嬭瘯鍗曡〃", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{ids}")
-    public R<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
-                          @PathVariable Long[] ids) {
-        return toAjax(testDemoService.deleteWithValidByIds(Arrays.asList(ids), true));
-    }
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestEncryptController.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestEncryptController.java
deleted file mode 100644
index 6abe4e1..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestEncryptController.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.ruoyi.demo.controller;
-
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.demo.domain.TestDemoEncrypt;
-import com.ruoyi.demo.mapper.TestDemoEncryptMapper;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-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 java.util.HashMap;
-import java.util.Map;
-
-
-/**
- * 娴嬭瘯鏁版嵁搴撳姞瑙e瘑鍔熻兘
- *
- * @author Lion Li
- */
-@Validated
-@RestController
-@RequestMapping("/demo/encrypt")
-public class TestEncryptController {
-
-    @Autowired
-    private TestDemoEncryptMapper mapper;
-    @Value("${mybatis-encryptor.enable}")
-    private Boolean encryptEnable;
-
-    /**
-     * 娴嬭瘯鏁版嵁搴撳姞瑙e瘑
-     *
-     * @param key   娴嬭瘯key
-     * @param value 娴嬭瘯value
-     */
-    @GetMapping()
-    public R<Map<String, TestDemoEncrypt>> test(String key, String value) {
-        if (!encryptEnable) {
-            throw new RuntimeException("鍔犲瘑鍔熻兘鏈紑鍚�!");
-        }
-        Map<String, TestDemoEncrypt> map = new HashMap<>(2);
-        TestDemoEncrypt demo = new TestDemoEncrypt();
-        demo.setTestKey(key);
-        demo.setValue(value);
-        mapper.insert(demo);
-        map.put("鍔犲瘑", demo);
-        TestDemoEncrypt testDemo = mapper.selectById(demo.getId());
-        map.put("瑙e瘑", testDemo);
-        return R.ok(map);
-    }
-
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestExcelController.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestExcelController.java
deleted file mode 100644
index 8a48dc6..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestExcelController.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package com.ruoyi.demo.controller;
-
-import cn.hutool.core.collection.CollUtil;
-import com.ruoyi.common.excel.utils.ExcelUtil;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import jakarta.servlet.http.HttpServletResponse;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 娴嬭瘯Excel鍔熻兘
- *
- * @author Lion Li
- */
-@RestController
-@RequestMapping("/demo/excel")
-public class TestExcelController {
-
-    /**
-     * 鍗曞垪琛ㄥ鏁版嵁
-     */
-    @GetMapping("/exportTemplateOne")
-    public void exportTemplateOne(HttpServletResponse response) {
-        Map<String, String> map = new HashMap<>();
-        map.put("title", "鍗曞垪琛ㄥ鏁版嵁");
-        map.put("test1", "鏁版嵁娴嬭瘯1");
-        map.put("test2", "鏁版嵁娴嬭瘯2");
-        map.put("test3", "鏁版嵁娴嬭瘯3");
-        map.put("test4", "鏁版嵁娴嬭瘯4");
-        map.put("testTest", "666");
-        List<TestObj> list = new ArrayList<>();
-        list.add(new TestObj("鍗曞垪琛ㄦ祴璇�1", "鍒楄〃娴嬭瘯1", "鍒楄〃娴嬭瘯2", "鍒楄〃娴嬭瘯3", "鍒楄〃娴嬭瘯4"));
-        list.add(new TestObj("鍗曞垪琛ㄦ祴璇�2", "鍒楄〃娴嬭瘯5", "鍒楄〃娴嬭瘯6", "鍒楄〃娴嬭瘯7", "鍒楄〃娴嬭瘯8"));
-        list.add(new TestObj("鍗曞垪琛ㄦ祴璇�3", "鍒楄〃娴嬭瘯9", "鍒楄〃娴嬭瘯10", "鍒楄〃娴嬭瘯11", "鍒楄〃娴嬭瘯12"));
-        ExcelUtil.exportTemplate(CollUtil.newArrayList(map, list), "鍗曞垪琛�.xlsx", "excel/鍗曞垪琛�.xlsx", response);
-    }
-
-    /**
-     * 澶氬垪琛ㄥ鏁版嵁
-     */
-    @GetMapping("/exportTemplateMuliti")
-    public void exportTemplateMuliti(HttpServletResponse response) {
-        Map<String, String> map = new HashMap<>();
-        map.put("title1", "鏍囬1");
-        map.put("title2", "鏍囬2");
-        map.put("title3", "鏍囬3");
-        map.put("title4", "鏍囬4");
-        map.put("author", "Lion Li");
-        List<TestObj1> list1 = new ArrayList<>();
-        list1.add(new TestObj1("list1娴嬭瘯1", "list1娴嬭瘯2", "list1娴嬭瘯3"));
-        list1.add(new TestObj1("list1娴嬭瘯4", "list1娴嬭瘯5", "list1娴嬭瘯6"));
-        list1.add(new TestObj1("list1娴嬭瘯7", "list1娴嬭瘯8", "list1娴嬭瘯9"));
-        List<TestObj1> list2 = new ArrayList<>();
-        list2.add(new TestObj1("list2娴嬭瘯1", "list2娴嬭瘯2", "list2娴嬭瘯3"));
-        list2.add(new TestObj1("list2娴嬭瘯4", "list2娴嬭瘯5", "list2娴嬭瘯6"));
-        List<TestObj1> list3 = new ArrayList<>();
-        list3.add(new TestObj1("list3娴嬭瘯1", "list3娴嬭瘯2", "list3娴嬭瘯3"));
-        List<TestObj1> list4 = new ArrayList<>();
-        list4.add(new TestObj1("list4娴嬭瘯1", "list4娴嬭瘯2", "list4娴嬭瘯3"));
-        list4.add(new TestObj1("list4娴嬭瘯4", "list4娴嬭瘯5", "list4娴嬭瘯6"));
-        list4.add(new TestObj1("list4娴嬭瘯7", "list4娴嬭瘯8", "list4娴嬭瘯9"));
-        list4.add(new TestObj1("list4娴嬭瘯10", "list4娴嬭瘯11", "list4娴嬭瘯12"));
-        Map<String, Object> multiListMap = new HashMap<>();
-        multiListMap.put("map", map);
-        multiListMap.put("data1", list1);
-        multiListMap.put("data2", list2);
-        multiListMap.put("data3", list3);
-        multiListMap.put("data4", list4);
-        ExcelUtil.exportTemplateMultiList(multiListMap, "澶氬垪琛�.xlsx", "excel/澶氬垪琛�.xlsx", response);
-    }
-
-    @Data
-    @AllArgsConstructor
-    static class TestObj1 {
-        private String test1;
-        private String test2;
-        private String test3;
-    }
-
-    @Data
-    @AllArgsConstructor
-    static class TestObj {
-        private String name;
-        private String list1;
-        private String list2;
-        private String list3;
-        private String list4;
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestI18nController.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestI18nController.java
deleted file mode 100644
index 5cc6a2e..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestI18nController.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package com.ruoyi.demo.controller;
-
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.core.utils.MessageUtils;
-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 jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-
-
-/**
- * 娴嬭瘯鍥介檯鍖�
- *
- * @author Lion Li
- */
-@Validated
-@RestController
-@RequestMapping("/demo/i18n")
-public class TestI18nController {
-
-    /**
-     * 閫氳繃code鑾峰彇鍥介檯鍖栧唴瀹�
-     * code涓� messages.properties 涓殑 key
-     * <p>
-     * 娴嬭瘯浣跨敤 user.register.success
-     *
-     * @param code 鍥介檯鍖朿ode
-     */
-    @GetMapping()
-    public R<Void> get(String code) {
-        return R.ok(MessageUtils.message(code));
-    }
-
-    /**
-     * Validator 鏍¢獙鍥介檯鍖�
-     * 涓嶄紶鍊� 鍒嗗埆鏌ョ湅寮傚父杩斿洖
-     * <p>
-     * 娴嬭瘯浣跨敤 not.null
-     */
-    @GetMapping("/test1")
-    public R<Void> test1(@NotBlank(message = "{not.null}") String str) {
-        return R.ok(str);
-    }
-
-    /**
-     * Bean 鏍¢獙鍥介檯鍖�
-     * 涓嶄紶鍊� 鍒嗗埆鏌ョ湅寮傚父杩斿洖
-     * <p>
-     * 娴嬭瘯浣跨敤 not.null
-     */
-    @GetMapping("/test2")
-    public R<TestI18nBo> test2(@Validated TestI18nBo bo) {
-        return R.ok(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-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestSensitiveController.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestSensitiveController.java
deleted file mode 100644
index 499effe..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestSensitiveController.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package com.ruoyi.demo.controller;
-
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.common.sensitive.annotation.Sensitive;
-import com.ruoyi.common.sensitive.core.SensitiveStrategy;
-import lombok.Data;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * 娴嬭瘯鏁版嵁鑴辨晱鎺у埗鍣�
- * <p>
- * 榛樿绠$悊鍛樹笉杩囨护
- * 闇�鑷鏍规嵁涓氬姟閲嶅啓瀹炵幇
- *
- * @author Lion Li
- * @version 3.6.0
- * @see com.ruoyi.common.sensitive.core.SensitiveService
- */
-@RestController
-@RequestMapping("/demo/sensitive")
-public class TestSensitiveController extends BaseController {
-
-    /**
-     * 娴嬭瘯鏁版嵁鑴辨晱
-     */
-    @GetMapping("/test")
-    public R<TestSensitive> test() {
-        TestSensitive testSensitive = new TestSensitive();
-        testSensitive.setIdCard("210397198608215431");
-        testSensitive.setPhone("17640125371");
-        testSensitive.setAddress("鍖椾含甯傛湞闃冲尯鏌愭煇鍥涘悎闄�1203瀹�");
-        testSensitive.setEmail("17640125371@163.com");
-        testSensitive.setBankCard("6226456952351452853");
-        return R.ok(testSensitive);
-    }
-
-    @Data
-    static class TestSensitive {
-
-        /**
-         * 韬唤璇�
-         */
-        @Sensitive(strategy = SensitiveStrategy.ID_CARD)
-        private String idCard;
-
-        /**
-         * 鐢佃瘽
-         */
-        @Sensitive(strategy = SensitiveStrategy.PHONE)
-        private String phone;
-
-        /**
-         * 鍦板潃
-         */
-        @Sensitive(strategy = SensitiveStrategy.ADDRESS)
-        private String address;
-
-        /**
-         * 閭
-         */
-        @Sensitive(strategy = SensitiveStrategy.EMAIL)
-        private String email;
-
-        /**
-         * 閾惰鍗�
-         */
-        @Sensitive(strategy = SensitiveStrategy.BANK_CARD)
-        private String bankCard;
-
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestTreeController.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestTreeController.java
deleted file mode 100644
index 51a680d..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestTreeController.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package com.ruoyi.demo.controller;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.core.validate.AddGroup;
-import com.ruoyi.common.core.validate.EditGroup;
-import com.ruoyi.common.core.validate.QueryGroup;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.common.excel.utils.ExcelUtil;
-import com.ruoyi.common.idempotent.annotation.RepeatSubmit;
-import com.ruoyi.common.log.annotation.Log;
-import com.ruoyi.common.log.enums.BusinessType;
-import com.ruoyi.demo.domain.bo.TestTreeBo;
-import com.ruoyi.demo.domain.vo.TestTreeVo;
-import com.ruoyi.demo.service.ITestTreeService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import jakarta.servlet.http.HttpServletResponse;
-import jakarta.validation.constraints.NotEmpty;
-import jakarta.validation.constraints.NotNull;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * 娴嬭瘯鏍戣〃Controller
- *
- * @author Lion Li
- * @date 2021-07-26
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/demo/tree")
-public class TestTreeController extends BaseController {
-
-    private final ITestTreeService testTreeService;
-
-    /**
-     * 鏌ヨ娴嬭瘯鏍戣〃鍒楄〃
-     */
-    @SaCheckPermission("demo:tree:list")
-    @GetMapping("/list")
-    public R<List<TestTreeVo>> list(@Validated(QueryGroup.class) TestTreeBo bo) {
-        List<TestTreeVo> list = testTreeService.queryList(bo);
-        return R.ok(list);
-    }
-
-    /**
-     * 瀵煎嚭娴嬭瘯鏍戣〃鍒楄〃
-     */
-    @SaCheckPermission("demo:tree:export")
-    @Log(title = "娴嬭瘯鏍戣〃", businessType = BusinessType.EXPORT)
-    @GetMapping("/export")
-    public void export(@Validated TestTreeBo bo, HttpServletResponse response) {
-        List<TestTreeVo> list = testTreeService.queryList(bo);
-        ExcelUtil.exportExcel(list, "娴嬭瘯鏍戣〃", TestTreeVo.class, response);
-    }
-
-    /**
-     * 鑾峰彇娴嬭瘯鏍戣〃璇︾粏淇℃伅
-     *
-     * @param id 娴嬭瘯鏍慖D
-     */
-    @SaCheckPermission("demo:tree:query")
-    @GetMapping("/{id}")
-    public R<TestTreeVo> getInfo(@NotNull(message = "涓婚敭涓嶈兘涓虹┖")
-                                 @PathVariable("id") Long id) {
-        return R.ok(testTreeService.queryById(id));
-    }
-
-    /**
-     * 鏂板娴嬭瘯鏍戣〃
-     */
-    @SaCheckPermission("demo:tree:add")
-    @Log(title = "娴嬭瘯鏍戣〃", businessType = BusinessType.INSERT)
-    @RepeatSubmit
-    @PostMapping()
-    public R<Void> add(@Validated(AddGroup.class) @RequestBody TestTreeBo bo) {
-        return toAjax(testTreeService.insertByBo(bo));
-    }
-
-    /**
-     * 淇敼娴嬭瘯鏍戣〃
-     */
-    @SaCheckPermission("demo:tree:edit")
-    @Log(title = "娴嬭瘯鏍戣〃", businessType = BusinessType.UPDATE)
-    @RepeatSubmit
-    @PutMapping()
-    public R<Void> edit(@Validated(EditGroup.class) @RequestBody TestTreeBo bo) {
-        return toAjax(testTreeService.updateByBo(bo));
-    }
-
-    /**
-     * 鍒犻櫎娴嬭瘯鏍戣〃
-     *
-     * @param ids 娴嬭瘯鏍慖D涓�
-     */
-    @SaCheckPermission("demo:tree:remove")
-    @Log(title = "娴嬭瘯鏍戣〃", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{ids}")
-    public R<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
-                          @PathVariable Long[] ids) {
-        return toAjax(testTreeService.deleteWithValidByIds(Arrays.asList(ids), true));
-    }
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/WeSocketController.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/WeSocketController.java
deleted file mode 100644
index 49595c7..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/WeSocketController.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.ruoyi.demo.controller;
-
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.websocket.dto.WebSocketMessageDto;
-import com.ruoyi.common.websocket.utils.WebSocketUtils;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * WebSocket 婕旂ず妗堜緥
- *
- * @author zendwang
- */
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/demo/websocket")
-@Slf4j
-public class WeSocketController {
-
-    /**
-     * 鍙戝竷娑堟伅
-     *
-     * @param dto 鍙戦�佸唴瀹�
-     */
-    @GetMapping("/send")
-    public R<Void> send(WebSocketMessageDto dto) throws InterruptedException {
-        WebSocketUtils.publishMessage(dto);
-        return R.ok("鎿嶄綔鎴愬姛");
-    }
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/package-info.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/package-info.java
deleted file mode 100644
index 4239668..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package com.ruoyi.demo.controller;
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/queue/BoundedQueueController.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/queue/BoundedQueueController.java
deleted file mode 100644
index 604a38d..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/queue/BoundedQueueController.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package com.ruoyi.demo.controller.queue;
-
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.redis.utils.QueueUtils;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * 鏈夌晫闃熷垪 婕旂ず妗堜緥
- * <p>
- * 杞婚噺绾ч槦鍒� 閲嶉噺绾ф暟鎹噺 璇蜂娇鐢� MQ
- * <p>
- * 闆嗙兢娴嬭瘯閫氳繃 鍚屼竴涓暟鎹彧浼氳娑堣垂涓�娆� 鍋氬ソ浜嬪姟琛ュ伩
- * 闆嗙兢娴嬭瘯娴佺▼ 鍦ㄥ叾涓竴鍙板彂閫佹暟鎹� 涓ょ鍒嗗埆璋冪敤鑾峰彇鎺ュ彛 涓�娆¤幏鍙栦竴鏉�
- *
- * @author Lion Li
- * @version 3.6.0
- */
-@Slf4j
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/demo/queue/bounded")
-public class BoundedQueueController {
-
-
-    /**
-     * 娣诲姞闃熷垪鏁版嵁
-     *
-     * @param queueName 闃熷垪鍚�
-     * @param capacity  瀹归噺
-     */
-    @GetMapping("/add")
-    public R<Void> add(String queueName, int capacity) {
-        // 鐢ㄥ畬浜嗕竴瀹氳閿�姣� 鍚﹀垯浼氫竴鐩村瓨鍦�
-        boolean b = QueueUtils.destroyQueue(queueName);
-        log.info("閫氶亾: {} , 鍒犻櫎: {}", queueName, b);
-        // 鍒濆鍖栬缃竴娆″嵆鍙�
-        if (QueueUtils.trySetBoundedQueueCapacity(queueName, capacity)) {
-            log.info("閫氶亾: {} , 璁剧疆瀹归噺: {}", queueName, capacity);
-        } else {
-            log.info("閫氶亾: {} , 璁剧疆瀹归噺澶辫触", queueName);
-            return R.fail("鎿嶄綔澶辫触");
-        }
-        for (int i = 0; i < 11; i++) {
-            String data = "data-" + i;
-            boolean flag = QueueUtils.addBoundedQueueObject(queueName, data);
-            if (flag == false) {
-                log.info("閫氶亾: {} , 鍙戦�佹暟鎹�: {} 澶辫触, 閫氶亾宸叉弧", queueName, data);
-            } else {
-                log.info("閫氶亾: {} , 鍙戦�佹暟鎹�: {}", queueName, data);
-            }
-        }
-        return R.ok("鎿嶄綔鎴愬姛");
-    }
-
-    /**
-     * 鍒犻櫎闃熷垪鏁版嵁
-     *
-     * @param queueName 闃熷垪鍚�
-     */
-    @GetMapping("/remove")
-    public R<Void> remove(String queueName) {
-        String data = "data-" + 5;
-        if (QueueUtils.removeQueueObject(queueName, data)) {
-            log.info("閫氶亾: {} , 鍒犻櫎鏁版嵁: {}", queueName, data);
-        } else {
-            return R.fail("鎿嶄綔澶辫触");
-        }
-        return R.ok("鎿嶄綔鎴愬姛");
-    }
-
-    /**
-     * 鑾峰彇闃熷垪鏁版嵁
-     *
-     * @param queueName 闃熷垪鍚�
-     */
-    @GetMapping("/get")
-    public R<Void> get(String queueName) {
-        String data;
-        do {
-            data = QueueUtils.getQueueObject(queueName);
-            log.info("閫氶亾: {} , 鑾峰彇鏁版嵁: {}", queueName, data);
-        } while (data != null);
-        return R.ok("鎿嶄綔鎴愬姛");
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/queue/DelayedQueueController.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/queue/DelayedQueueController.java
deleted file mode 100644
index 3587c2b..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/queue/DelayedQueueController.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package com.ruoyi.demo.controller.queue;
-
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.redis.utils.QueueUtils;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * 寤惰繜闃熷垪 婕旂ず妗堜緥
- * <p>
- * 杞婚噺绾ч槦鍒� 閲嶉噺绾ф暟鎹噺 璇蜂娇鐢� MQ
- * 渚嬪: 鍒涘缓璁㈠崟30鍒嗛挓鍚庤繃鏈熷鐞�
- * <p>
- * 闆嗙兢娴嬭瘯閫氳繃 鍚屼竴涓暟鎹彧浼氳娑堣垂涓�娆� 鍋氬ソ浜嬪姟琛ュ伩
- * 闆嗙兢娴嬭瘯娴佺▼ 涓ゅ彴闆嗙兢鍒嗗埆寮�鍚闃� 鍦ㄥ叾涓竴鍙板彂閫佹暟鎹� 瑙傚療鎺ユ敹娑堟伅鐨勮寰�
- *
- * @author Lion Li
- * @version 3.6.0
- */
-@Slf4j
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/demo/queue/delayed")
-public class DelayedQueueController {
-
-    /**
-     * 璁㈤槄闃熷垪
-     *
-     * @param queueName 闃熷垪鍚�
-     */
-    @GetMapping("/subscribe")
-    public R<Void> subscribe(String queueName) {
-        log.info("閫氶亾: {} 鐩戝惉涓�......", queueName);
-        // 椤圭洰鍒濆鍖栬缃竴娆″嵆鍙�
-        QueueUtils.subscribeBlockingQueue(queueName, (String orderNum) -> {
-            // 瑙傚療鎺ユ敹鏃堕棿
-            log.info("閫氶亾: {}, 鏀跺埌鏁版嵁: {}", queueName, orderNum);
-        });
-        return R.ok("鎿嶄綔鎴愬姛");
-    }
-
-    /**
-     * 娣诲姞闃熷垪鏁版嵁
-     *
-     * @param queueName 闃熷垪鍚�
-     * @param orderNum  璁㈠崟鍙�
-     * @param time      寤惰繜鏃堕棿(绉�)
-     */
-    @GetMapping("/add")
-    public R<Void> add(String queueName, String orderNum, Long time) {
-        QueueUtils.addDelayedQueueObject(queueName, orderNum, time, TimeUnit.SECONDS);
-        // 瑙傚療鍙戦�佹椂闂�
-        log.info("閫氶亾: {} , 鍙戦�佹暟鎹�: {}", queueName, orderNum);
-        return R.ok("鎿嶄綔鎴愬姛");
-    }
-
-    /**
-     * 鍒犻櫎闃熷垪鏁版嵁
-     *
-     * @param queueName 闃熷垪鍚�
-     * @param orderNum  璁㈠崟鍙�
-     */
-    @GetMapping("/remove")
-    public R<Void> remove(String queueName, String orderNum) {
-        if (QueueUtils.removeDelayedQueueObject(queueName, orderNum)) {
-            log.info("閫氶亾: {} , 鍒犻櫎鏁版嵁: {}", queueName, orderNum);
-        } else {
-            return R.fail("鎿嶄綔澶辫触");
-        }
-        return R.ok("鎿嶄綔鎴愬姛");
-    }
-
-    /**
-     * 閿�姣侀槦鍒�
-     *
-     * @param queueName 闃熷垪鍚�
-     */
-    @GetMapping("/destroy")
-    public R<Void> destroy(String queueName) {
-        // 鐢ㄥ畬浜嗕竴瀹氳閿�姣� 鍚﹀垯浼氫竴鐩村瓨鍦�
-        QueueUtils.destroyDelayedQueue(queueName);
-        return R.ok("鎿嶄綔鎴愬姛");
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/queue/PriorityDemo.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/queue/PriorityDemo.java
deleted file mode 100644
index c86c92a..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/queue/PriorityDemo.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.ruoyi.demo.controller.queue;
-
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-/**
- * 瀹炰綋绫� 娉ㄦ剰涓嶅厑璁镐娇鐢ㄥ唴閮ㄧ被 鍚﹀垯浼氭壘涓嶅埌绫�
- *
- * @author Lion Li
- * @version 3.6.0
- */
-@Data
-@NoArgsConstructor
-public class PriorityDemo implements Comparable<PriorityDemo> {
-    private String name;
-    private Integer orderNum;
-
-    @Override
-    public int compareTo(PriorityDemo other) {
-        return Integer.compare(getOrderNum(), other.getOrderNum());
-    }
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/queue/PriorityQueueController.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/queue/PriorityQueueController.java
deleted file mode 100644
index fcccf14..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/queue/PriorityQueueController.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package com.ruoyi.demo.controller.queue;
-
-import cn.hutool.core.util.RandomUtil;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.redis.utils.QueueUtils;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * 浼樺厛闃熷垪 婕旂ず妗堜緥
- * <p>
- * 杞婚噺绾ч槦鍒� 閲嶉噺绾ф暟鎹噺 璇蜂娇鐢� MQ
- * <p>
- * 闆嗙兢娴嬭瘯閫氳繃 鍚屼竴涓秷鎭彧浼氳娑堣垂涓�娆� 鍋氬ソ浜嬪姟琛ュ伩
- * 闆嗙兢娴嬭瘯娴佺▼ 鍦ㄥ叾涓竴鍙板彂閫佹暟鎹� 涓ょ鍒嗗埆璋冪敤鑾峰彇鎺ュ彛 涓�娆¤幏鍙栦竴鏉�
- *
- * @author Lion Li
- * @version 3.6.0
- */
-@Slf4j
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/demo/queue/priority")
-public class PriorityQueueController {
-
-    /**
-     * 娣诲姞闃熷垪鏁版嵁
-     *
-     * @param queueName 闃熷垪鍚�
-     */
-    @GetMapping("/add")
-    public R<Void> add(String queueName) {
-        // 鐢ㄥ畬浜嗕竴瀹氳閿�姣� 鍚﹀垯浼氫竴鐩村瓨鍦�
-        boolean b = QueueUtils.destroyQueue(queueName);
-        log.info("閫氶亾: {} , 鍒犻櫎: {}", queueName, b);
-
-        for (int i = 0; i < 10; i++) {
-            int randomNum = RandomUtil.randomInt(10);
-            PriorityDemo data = new PriorityDemo();
-            data.setName("data-" + i);
-            data.setOrderNum(randomNum);
-            if (QueueUtils.addPriorityQueueObject(queueName, data)) {
-                log.info("閫氶亾: {} , 鍙戦�佹暟鎹�: {}", queueName, data);
-            } else {
-                log.info("閫氶亾: {} , 鍙戦�佹暟鎹�: {}, 鍙戦�佸け璐�", queueName, data);
-            }
-        }
-        return R.ok("鎿嶄綔鎴愬姛");
-    }
-
-    /**
-     * 鍒犻櫎闃熷垪鏁版嵁
-     *
-     * @param queueName 闃熷垪鍚�
-     * @param name      瀵硅薄鍚�
-     * @param orderNum  鎺掑簭鍙�
-     */
-    @GetMapping("/remove")
-    public R<Void> remove(String queueName, String name, Integer orderNum) {
-        PriorityDemo data = new PriorityDemo();
-        data.setName(name);
-        data.setOrderNum(orderNum);
-        if (QueueUtils.removeQueueObject(queueName, data)) {
-            log.info("閫氶亾: {} , 鍒犻櫎鏁版嵁: {}", queueName, data);
-        } else {
-            return R.fail("鎿嶄綔澶辫触");
-        }
-        return R.ok("鎿嶄綔鎴愬姛");
-    }
-
-    /**
-     * 鑾峰彇闃熷垪鏁版嵁
-     *
-     * @param queueName 闃熷垪鍚�
-     */
-    @GetMapping("/get")
-    public R<Void> get(String queueName) {
-        PriorityDemo data;
-        do {
-            data = QueueUtils.getQueueObject(queueName);
-            log.info("閫氶亾: {} , 鑾峰彇鏁版嵁: {}", queueName, data);
-        } while (data != null);
-        return R.ok("鎿嶄綔鎴愬姛");
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestDemo.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestDemo.java
deleted file mode 100644
index 2702db2..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestDemo.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package com.ruoyi.demo.domain;
-
-import com.baomidou.mybatisplus.annotation.*;
-import com.ruoyi.common.tenant.core.TenantEntity;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import java.io.Serial;
-
-/**
- * 娴嬭瘯鍗曡〃瀵硅薄 test_demo
- *
- * @author Lion Li
- * @date 2021-07-26
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("test_demo")
-public class TestDemo extends TenantEntity {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 涓婚敭
-     */
-    @TableId(value = "id")
-    private Long id;
-
-    /**
-     * 閮ㄩ棬id
-     */
-    private Long deptId;
-
-    /**
-     * 鐢ㄦ埛id
-     */
-    private Long userId;
-
-    /**
-     * 鎺掑簭鍙�
-     */
-    @OrderBy(asc = false, sort = 1)
-    private Integer orderNum;
-
-    /**
-     * key閿�
-     */
-    private String testKey;
-
-    /**
-     * 鍊�
-     */
-    private String value;
-
-    /**
-     * 鐗堟湰
-     */
-    @Version
-    private Long version;
-
-    /**
-     * 鍒犻櫎鏍囧織
-     */
-    @TableLogic
-    private Long delFlag;
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestDemoEncrypt.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestDemoEncrypt.java
deleted file mode 100644
index 0214e8d..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestDemoEncrypt.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.ruoyi.demo.domain;
-
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.ruoyi.common.encrypt.annotation.EncryptField;
-import com.ruoyi.common.encrypt.enumd.AlgorithmType;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("test_demo")
-public class TestDemoEncrypt extends TestDemo {
-
-    /**
-     * key閿�
-     */
-    // @EncryptField(algorithm=AlgorithmType.SM2, privateKey = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgZSlOvw8FBiH+aFJWLYZP/VRjg9wjfRarTkGBZd/T3N+gCgYIKoEcz1UBgi2hRANCAAR5DGuQwJqkxnbCsP+iPSDoHWIF4RwcR5EsSvT8QPxO1wRkR2IhCkzvRb32x2CUgJFdvoqVqfApFDPZzShqzBwX", publicKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEeQxrkMCapMZ2wrD/oj0g6B1iBeEcHEeRLEr0/ED8TtcEZEdiIQpM70W99sdglICRXb6KlanwKRQz2c0oaswcFw==")
-    @EncryptField(algorithm = AlgorithmType.RSA, privateKey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBANBBEeueWlXlkkj2+WY5l+IWe42d8b5K28g+G/CFKC/yYAEHtqGlCsBOrb+YBkG9mPzmuYA/n9k0NFIc8E8yY5vZQaroyFBrTTWEzG9RY2f7Y3svVyybs6jpXSUs4xff8abo7wL1Y/wUaeatTViamxYnyTvdTmLm3d+JjRij68rxAgMBAAECgYAB0TnhXraSopwIVRfmboea1b0upl+BUdTJcmci412UjrKr5aE695ZLPkXbFXijVu7HJlyyv94NVUdaMACV7Ku/S2RuNB70M7YJm8rAjHFC3/i2ZeIM60h1Ziy4QKv0XM3pRATlDCDNhC1WUrtQCQSgU8kcp6eUUppruOqDzcY04QJBAPm9+sBP9CwDRgy3e5+V8aZtJkwDstb0lVVV/KY890cydVxiCwvX3fqVnxKMlb+x0YtH0sb9v+71xvK2lGobaRECQQDVePU6r/cCEfpc+nkWF6osAH1f8Mux3rYv2DoBGvaPzV2BGfsLed4neRfCwWNCKvGPCdW+L0xMJg8+RwaoBUPhAkAT5kViqXxFPYWJYd1h2+rDXhMdH3ZSlm6HvDBDdrwlWinr0Iwcx3iSjPV93uHXwm118aUj4fg3LDJMCKxOwBxhAkByrQXfvwOMYygBprRBf/j0plazoWFrbd6lGR0f1uI5IfNnFRPdeFw1DEINZ2Hw+6zEUF44SqRMC+4IYJNc02dBAkBCgy7RvfyV/A7N6kKXxTHauY0v6XwSSvpeKtRJkbIcRWOdIYvaHO9L7cklj3vIEdwjSUp9K4VTBYYlmAz1xh03", publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQQRHrnlpV5ZJI9vlmOZfiFnuNnfG+StvIPhvwhSgv8mABB7ahpQrATq2/mAZBvZj85rmAP5/ZNDRSHPBPMmOb2UGq6MhQa001hMxvUWNn+2N7L1csm7Oo6V0lLOMX3/Gm6O8C9WP8FGnmrU1YmpsWJ8k73U5i5t3fiY0Yo+vK8QIDAQAB")
-    private String testKey;
-
-    /**
-     * 鍊�
-     */
-    // @EncryptField // 浠�涔堜篃涓嶅啓璧伴粯璁ml閰嶇疆
-    // @EncryptField(algorithm = AlgorithmType.SM4, password = "10rfylhtccpuyke5")
-    @EncryptField(algorithm = AlgorithmType.AES, password = "10rfylhtccpuyke5")
-    private String value;
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestTree.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestTree.java
deleted file mode 100644
index f644bfd..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestTree.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.ruoyi.demo.domain;
-
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableLogic;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.baomidou.mybatisplus.annotation.Version;
-import com.ruoyi.common.tenant.core.TenantEntity;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import java.io.Serial;
-
-/**
- * 娴嬭瘯鏍戣〃瀵硅薄 test_tree
- *
- * @author Lion Li
- * @date 2021-07-26
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("test_tree")
-public class TestTree extends TenantEntity {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 涓婚敭
-     */
-    @TableId(value = "id")
-    private Long id;
-
-    /**
-     * 鐖禝D
-     */
-    private Long parentId;
-
-    /**
-     * 閮ㄩ棬id
-     */
-    private Long deptId;
-
-    /**
-     * 鐢ㄦ埛id
-     */
-    private Long userId;
-
-    /**
-     * 鏍戣妭鐐瑰悕
-     */
-    private String treeName;
-
-    /**
-     * 鐗堟湰
-     */
-    @Version
-    private Long version;
-
-    /**
-     * 鍒犻櫎鏍囧織
-     */
-    @TableLogic
-    private Long delFlag;
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/bo/TestDemoBo.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/bo/TestDemoBo.java
deleted file mode 100644
index d37f4a6..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/bo/TestDemoBo.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.ruoyi.demo.domain.bo;
-
-import com.ruoyi.common.core.validate.AddGroup;
-import com.ruoyi.common.core.validate.EditGroup;
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-import com.ruoyi.demo.domain.TestDemo;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-
-/**
- * 娴嬭瘯鍗曡〃涓氬姟瀵硅薄 test_demo
- *
- * @author Lion Li
- * @date 2021-07-26
- */
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@AutoMapper(target = TestDemo.class, reverseConvertGenerate = false)
-public class TestDemoBo extends BaseEntity {
-
-    /**
-     * 涓婚敭
-     */
-    @NotNull(message = "涓婚敭涓嶈兘涓虹┖", groups = {EditGroup.class})
-    private Long id;
-
-    /**
-     * 閮ㄩ棬id
-     */
-    @NotNull(message = "閮ㄩ棬id涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
-    private Long deptId;
-
-    /**
-     * 鐢ㄦ埛id
-     */
-    @NotNull(message = "鐢ㄦ埛id涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
-    private Long userId;
-
-    /**
-     * 鎺掑簭鍙�
-     */
-    @NotNull(message = "鎺掑簭鍙蜂笉鑳戒负绌�", groups = {AddGroup.class, EditGroup.class})
-    private Integer orderNum;
-
-    /**
-     * key閿�
-     */
-    @NotBlank(message = "key閿笉鑳戒负绌�", groups = {AddGroup.class, EditGroup.class})
-    private String testKey;
-
-    /**
-     * 鍊�
-     */
-    @NotBlank(message = "鍊间笉鑳戒负绌�", groups = {AddGroup.class, EditGroup.class})
-    private String value;
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/bo/TestDemoImportVo.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/bo/TestDemoImportVo.java
deleted file mode 100644
index 26318e4..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/bo/TestDemoImportVo.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package com.ruoyi.demo.domain.bo;
-
-import com.alibaba.excel.annotation.ExcelProperty;
-import lombok.Data;
-
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-
-/**
- * 娴嬭瘯鍗曡〃涓氬姟瀵硅薄 test_demo
- *
- * @author Lion Li
- * @date 2021-07-26
- */
-@Data
-public class TestDemoImportVo {
-
-    /**
-     * 閮ㄩ棬id
-     */
-    @NotNull(message = "閮ㄩ棬id涓嶈兘涓虹┖")
-    @ExcelProperty(value = "閮ㄩ棬id")
-    private Long deptId;
-
-    /**
-     * 鐢ㄦ埛id
-     */
-    @NotNull(message = "鐢ㄦ埛id涓嶈兘涓虹┖")
-    @ExcelProperty(value = "鐢ㄦ埛id")
-    private Long userId;
-
-    /**
-     * 鎺掑簭鍙�
-     */
-    @NotNull(message = "鎺掑簭鍙蜂笉鑳戒负绌�")
-    @ExcelProperty(value = "鎺掑簭鍙�")
-    private Long orderNum;
-
-    /**
-     * key閿�
-     */
-    @NotBlank(message = "key閿笉鑳戒负绌�")
-    @ExcelProperty(value = "key閿�")
-    private String testKey;
-
-    /**
-     * 鍊�
-     */
-    @NotBlank(message = "鍊间笉鑳戒负绌�")
-    @ExcelProperty(value = "鍊�")
-    private String value;
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/bo/TestTreeBo.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/bo/TestTreeBo.java
deleted file mode 100644
index 688c738..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/bo/TestTreeBo.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.ruoyi.demo.domain.bo;
-
-import com.ruoyi.common.core.validate.AddGroup;
-import com.ruoyi.common.core.validate.EditGroup;
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-import com.ruoyi.demo.domain.TestTree;
-import io.github.linpeilie.annotations.AutoMapper;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * 娴嬭瘯鏍戣〃涓氬姟瀵硅薄 test_tree
- *
- * @author Lion Li
- * @date 2021-07-26
- */
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@AutoMapper(target = TestTree.class, reverseConvertGenerate = false)
-public class TestTreeBo extends BaseEntity {
-
-    /**
-     * 涓婚敭
-     */
-    @NotNull(message = "涓婚敭涓嶈兘涓虹┖", groups = {EditGroup.class})
-    private Long id;
-
-    /**
-     * 鐖禝D
-     */
-    private Long parentId;
-
-    /**
-     * 閮ㄩ棬id
-     */
-    @NotNull(message = "閮ㄩ棬id涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
-    private Long deptId;
-
-    /**
-     * 鐢ㄦ埛id
-     */
-    @NotNull(message = "鐢ㄦ埛id涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
-    private Long userId;
-
-    /**
-     * 鏍戣妭鐐瑰悕
-     */
-    @NotBlank(message = "鏍戣妭鐐瑰悕涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
-    private String treeName;
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/package-info.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/package-info.java
deleted file mode 100644
index e2da765..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package com.ruoyi.demo.domain;
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/vo/TestDemoVo.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/vo/TestDemoVo.java
deleted file mode 100644
index 32181c0..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/vo/TestDemoVo.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package com.ruoyi.demo.domain.vo;
-
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.alibaba.excel.annotation.ExcelProperty;
-import com.ruoyi.common.translation.annotation.Translation;
-import com.ruoyi.common.translation.constant.TransConstant;
-import com.ruoyi.demo.domain.TestDemo;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-
-
-/**
- * 娴嬭瘯鍗曡〃瑙嗗浘瀵硅薄 test_demo
- *
- * @author Lion Li
- * @date 2021-07-26
- */
-@Data
-@ExcelIgnoreUnannotated
-@AutoMapper(target = TestDemo.class)
-public class TestDemoVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 涓婚敭
-     */
-    @ExcelProperty(value = "涓婚敭")
-    private Long id;
-
-    /**
-     * 閮ㄩ棬id
-     */
-    @ExcelProperty(value = "閮ㄩ棬id")
-    private Long deptId;
-
-    /**
-     * 鐢ㄦ埛id
-     */
-    @ExcelProperty(value = "鐢ㄦ埛id")
-    private Long userId;
-
-    /**
-     * 鎺掑簭鍙�
-     */
-    @ExcelProperty(value = "鎺掑簭鍙�")
-    private Integer orderNum;
-
-    /**
-     * key閿�
-     */
-    @ExcelProperty(value = "key閿�")
-    private String testKey;
-
-    /**
-     * 鍊�
-     */
-    @ExcelProperty(value = "鍊�")
-    private String value;
-
-    /**
-     * 鍒涘缓鏃堕棿
-     */
-    @ExcelProperty(value = "鍒涘缓鏃堕棿")
-    private Date createTime;
-
-    /**
-     * 鍒涘缓浜�
-     */
-    @ExcelProperty(value = "鍒涘缓浜�")
-    private Long createBy;
-
-    /**
-     * 鍒涘缓浜鸿处鍙�
-     */
-    @Translation(type = TransConstant.USER_ID_TO_NAME, mapper = "createBy")
-    @ExcelProperty(value = "鍒涘缓浜鸿处鍙�")
-    private String createByName;
-
-    /**
-     * 鏇存柊鏃堕棿
-     */
-    @ExcelProperty(value = "鏇存柊鏃堕棿")
-    private Date updateTime;
-
-    /**
-     * 鏇存柊浜�
-     */
-    @ExcelProperty(value = "鏇存柊浜�")
-    private Long updateBy;
-
-    /**
-     * 鏇存柊浜鸿处鍙�
-     */
-    @Translation(type = TransConstant.USER_ID_TO_NAME, mapper = "updateBy")
-    @ExcelProperty(value = "鏇存柊浜鸿处鍙�")
-    private String updateByName;
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/vo/TestTreeVo.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/vo/TestTreeVo.java
deleted file mode 100644
index dc10580..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/vo/TestTreeVo.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package com.ruoyi.demo.domain.vo;
-
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.alibaba.excel.annotation.ExcelProperty;
-import com.ruoyi.demo.domain.TestTree;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-
-
-/**
- * 娴嬭瘯鏍戣〃瑙嗗浘瀵硅薄 test_tree
- *
- * @author Lion Li
- * @date 2021-07-26
- */
-@Data
-@ExcelIgnoreUnannotated
-@AutoMapper(target = TestTree.class)
-public class TestTreeVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 涓婚敭
-     */
-    private Long id;
-
-    /**
-     * 鐖秈d
-     */
-    @ExcelProperty(value = "鐖秈d")
-    private Long parentId;
-
-    /**
-     * 閮ㄩ棬id
-     */
-    @ExcelProperty(value = "閮ㄩ棬id")
-    private Long deptId;
-
-    /**
-     * 鐢ㄦ埛id
-     */
-    @ExcelProperty(value = "鐢ㄦ埛id")
-    private Long userId;
-
-    /**
-     * 鏍戣妭鐐瑰悕
-     */
-    @ExcelProperty(value = "鏍戣妭鐐瑰悕")
-    private String treeName;
-
-    /**
-     * 鍒涘缓鏃堕棿
-     */
-    @ExcelProperty(value = "鍒涘缓鏃堕棿")
-    private Date createTime;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestDemoEncryptMapper.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestDemoEncryptMapper.java
deleted file mode 100644
index 2a38d28..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestDemoEncryptMapper.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.ruoyi.demo.mapper;
-
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.demo.domain.TestDemoEncrypt;
-
-/**
- * 娴嬭瘯鍔犲瘑鍔熻兘
- *
- * @author Lion Li
- */
-public interface TestDemoEncryptMapper extends BaseMapperPlus<TestDemoEncrypt, TestDemoEncrypt> {
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java
deleted file mode 100644
index 6f9927f..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package com.ruoyi.demo.mapper;
-
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.core.toolkit.Constants;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.mybatis.annotation.DataColumn;
-import com.ruoyi.common.mybatis.annotation.DataPermission;
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.demo.domain.TestDemo;
-import com.ruoyi.demo.domain.vo.TestDemoVo;
-import org.apache.ibatis.annotations.Param;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * 娴嬭瘯鍗曡〃Mapper鎺ュ彛
- *
- * @author Lion Li
- * @date 2021-07-26
- */
-public interface TestDemoMapper extends BaseMapperPlus<TestDemo, TestDemoVo> {
-
-    @DataPermission({
-        @DataColumn(key = "deptName", value = "dept_id"),
-        @DataColumn(key = "userName", value = "user_id")
-    })
-    Page<TestDemoVo> customPageList(@Param("page") Page<TestDemo> page, @Param("ew") Wrapper<TestDemo> wrapper);
-
-    @Override
-    @DataPermission({
-        @DataColumn(key = "deptName", value = "dept_id"),
-        @DataColumn(key = "userName", value = "user_id")
-    })
-    <P extends IPage<TestDemo>> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper<TestDemo> queryWrapper);
-
-    @Override
-    @DataPermission({
-        @DataColumn(key = "deptName", value = "dept_id"),
-        @DataColumn(key = "userName", value = "user_id")
-    })
-    List<TestDemo> selectList(@Param(Constants.WRAPPER) Wrapper<TestDemo> queryWrapper);
-
-    @Override
-    @DataPermission({
-        @DataColumn(key = "deptName", value = "dept_id"),
-        @DataColumn(key = "userName", value = "user_id")
-    })
-    int updateById(@Param(Constants.ENTITY) TestDemo entity);
-
-    @Override
-    @DataPermission({
-        @DataColumn(key = "deptName", value = "dept_id"),
-        @DataColumn(key = "userName", value = "user_id")
-    })
-    int deleteBatchIds(@Param(Constants.COLL) Collection<?> idList);
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestTreeMapper.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestTreeMapper.java
deleted file mode 100644
index 04aadea..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestTreeMapper.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.ruoyi.demo.mapper;
-
-import com.ruoyi.common.mybatis.annotation.DataColumn;
-import com.ruoyi.common.mybatis.annotation.DataPermission;
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.demo.domain.TestTree;
-import com.ruoyi.demo.domain.vo.TestTreeVo;
-
-/**
- * 娴嬭瘯鏍戣〃Mapper鎺ュ彛
- *
- * @author Lion Li
- * @date 2021-07-26
- */
-@DataPermission({
-    @DataColumn(key = "deptName", value = "dept_id"),
-    @DataColumn(key = "userName", value = "user_id")
-})
-public interface TestTreeMapper extends BaseMapperPlus<TestTree, TestTreeVo> {
-
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/package-info.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/package-info.java
deleted file mode 100644
index 7243da9..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package com.ruoyi.demo.mapper;
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestDemoService.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestDemoService.java
deleted file mode 100644
index 542791d..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestDemoService.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package com.ruoyi.demo.service;
-
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.demo.domain.TestDemo;
-import com.ruoyi.demo.domain.bo.TestDemoBo;
-import com.ruoyi.demo.domain.vo.TestDemoVo;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * 娴嬭瘯鍗曡〃Service鎺ュ彛
- *
- * @author Lion Li
- * @date 2021-07-26
- */
-public interface ITestDemoService {
-
-    /**
-     * 鏌ヨ鍗曚釜
-     *
-     * @return
-     */
-    TestDemoVo queryById(Long id);
-
-    /**
-     * 鏌ヨ鍒楄〃
-     */
-    TableDataInfo<TestDemoVo> queryPageList(TestDemoBo bo, PageQuery pageQuery);
-
-    /**
-     * 鑷畾涔夊垎椤垫煡璇�
-     */
-    TableDataInfo<TestDemoVo> customPageList(TestDemoBo bo, PageQuery pageQuery);
-
-    /**
-     * 鏌ヨ鍒楄〃
-     */
-    List<TestDemoVo> queryList(TestDemoBo bo);
-
-    /**
-     * 鏍规嵁鏂板涓氬姟瀵硅薄鎻掑叆娴嬭瘯鍗曡〃
-     *
-     * @param bo 娴嬭瘯鍗曡〃鏂板涓氬姟瀵硅薄
-     * @return
-     */
-    Boolean insertByBo(TestDemoBo bo);
-
-    /**
-     * 鏍规嵁缂栬緫涓氬姟瀵硅薄淇敼娴嬭瘯鍗曡〃
-     *
-     * @param bo 娴嬭瘯鍗曡〃缂栬緫涓氬姟瀵硅薄
-     * @return
-     */
-    Boolean updateByBo(TestDemoBo bo);
-
-    /**
-     * 鏍¢獙骞跺垹闄ゆ暟鎹�
-     *
-     * @param ids     涓婚敭闆嗗悎
-     * @param isValid 鏄惁鏍¢獙,true-鍒犻櫎鍓嶆牎楠�,false-涓嶆牎楠�
-     * @return
-     */
-    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
-
-    /**
-     * 鎵归噺淇濆瓨
-     */
-    Boolean saveBatch(List<TestDemo> list);
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestTreeService.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestTreeService.java
deleted file mode 100644
index 366e515..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestTreeService.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.ruoyi.demo.service;
-
-import com.ruoyi.demo.domain.bo.TestTreeBo;
-import com.ruoyi.demo.domain.vo.TestTreeVo;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * 娴嬭瘯鏍戣〃Service鎺ュ彛
- *
- * @author Lion Li
- * @date 2021-07-26
- */
-public interface ITestTreeService {
-    /**
-     * 鏌ヨ鍗曚釜
-     *
-     * @return
-     */
-    TestTreeVo queryById(Long id);
-
-    /**
-     * 鏌ヨ鍒楄〃
-     */
-    List<TestTreeVo> queryList(TestTreeBo bo);
-
-    /**
-     * 鏍规嵁鏂板涓氬姟瀵硅薄鎻掑叆娴嬭瘯鏍戣〃
-     *
-     * @param bo 娴嬭瘯鏍戣〃鏂板涓氬姟瀵硅薄
-     * @return
-     */
-    Boolean insertByBo(TestTreeBo bo);
-
-    /**
-     * 鏍规嵁缂栬緫涓氬姟瀵硅薄淇敼娴嬭瘯鏍戣〃
-     *
-     * @param bo 娴嬭瘯鏍戣〃缂栬緫涓氬姟瀵硅薄
-     * @return
-     */
-    Boolean updateByBo(TestTreeBo bo);
-
-    /**
-     * 鏍¢獙骞跺垹闄ゆ暟鎹�
-     *
-     * @param ids     涓婚敭闆嗗悎
-     * @param isValid 鏄惁鏍¢獙,true-鍒犻櫎鍓嶆牎楠�,false-涓嶆牎楠�
-     * @return
-     */
-    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestDemoServiceImpl.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestDemoServiceImpl.java
deleted file mode 100644
index f51fcad..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestDemoServiceImpl.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package com.ruoyi.demo.service.impl;
-
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.core.utils.MapstructUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.demo.domain.TestDemo;
-import com.ruoyi.demo.domain.bo.TestDemoBo;
-import com.ruoyi.demo.domain.vo.TestDemoVo;
-import com.ruoyi.demo.mapper.TestDemoMapper;
-import com.ruoyi.demo.service.ITestDemoService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Service;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 娴嬭瘯鍗曡〃Service涓氬姟灞傚鐞�
- *
- * @author Lion Li
- * @date 2021-07-26
- */
-@RequiredArgsConstructor
-@Service
-public class TestDemoServiceImpl implements ITestDemoService {
-
-    private final TestDemoMapper baseMapper;
-
-    @Override
-    public TestDemoVo queryById(Long id) {
-        return baseMapper.selectVoById(id);
-    }
-
-    @Override
-    public TableDataInfo<TestDemoVo> queryPageList(TestDemoBo bo, PageQuery pageQuery) {
-        LambdaQueryWrapper<TestDemo> lqw = buildQueryWrapper(bo);
-        Page<TestDemoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
-        return TableDataInfo.build(result);
-    }
-
-    /**
-     * 鑷畾涔夊垎椤垫煡璇�
-     */
-    @Override
-    public TableDataInfo<TestDemoVo> customPageList(TestDemoBo bo, PageQuery pageQuery) {
-        LambdaQueryWrapper<TestDemo> lqw = buildQueryWrapper(bo);
-        Page<TestDemoVo> result = baseMapper.customPageList(pageQuery.build(), lqw);
-        return TableDataInfo.build(result);
-    }
-
-    @Override
-    public List<TestDemoVo> queryList(TestDemoBo bo) {
-        return baseMapper.selectVoList(buildQueryWrapper(bo));
-    }
-
-    private LambdaQueryWrapper<TestDemo> buildQueryWrapper(TestDemoBo bo) {
-        Map<String, Object> params = bo.getParams();
-        LambdaQueryWrapper<TestDemo> lqw = Wrappers.lambdaQuery();
-        lqw.like(StringUtils.isNotBlank(bo.getTestKey()), TestDemo::getTestKey, bo.getTestKey());
-        lqw.eq(StringUtils.isNotBlank(bo.getValue()), TestDemo::getValue, bo.getValue());
-        lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
-            TestDemo::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime"));
-        return lqw;
-    }
-
-    @Override
-    public Boolean insertByBo(TestDemoBo bo) {
-        TestDemo add = MapstructUtils.convert(bo, TestDemo.class);
-        validEntityBeforeSave(add);
-        boolean flag = baseMapper.insert(add) > 0;
-        if (flag) {
-            bo.setId(add.getId());
-        }
-        return flag;
-    }
-
-    @Override
-    public Boolean updateByBo(TestDemoBo bo) {
-        TestDemo update = MapstructUtils.convert(bo, TestDemo.class);
-        validEntityBeforeSave(update);
-        return baseMapper.updateById(update) > 0;
-    }
-
-    /**
-     * 淇濆瓨鍓嶇殑鏁版嵁鏍¢獙
-     *
-     * @param entity 瀹炰綋绫绘暟鎹�
-     */
-    private void validEntityBeforeSave(TestDemo entity) {
-        //TODO 鍋氫竴浜涙暟鎹牎楠�,濡傚敮涓�绾︽潫
-    }
-
-    @Override
-    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
-        if (isValid) {
-            //TODO 鍋氫竴浜涗笟鍔′笂鐨勬牎楠�,鍒ゆ柇鏄惁闇�瑕佹牎楠�
-        }
-        return baseMapper.deleteBatchIds(ids) > 0;
-    }
-
-    @Override
-    public Boolean saveBatch(List<TestDemo> list) {
-        return baseMapper.insertBatch(list);
-    }
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestTreeServiceImpl.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestTreeServiceImpl.java
deleted file mode 100644
index a46e126..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestTreeServiceImpl.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package com.ruoyi.demo.service.impl;
-
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.ruoyi.common.core.utils.MapstructUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.demo.domain.TestTree;
-import com.ruoyi.demo.domain.bo.TestTreeBo;
-import com.ruoyi.demo.domain.vo.TestTreeVo;
-import com.ruoyi.demo.mapper.TestTreeMapper;
-import com.ruoyi.demo.service.ITestTreeService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Service;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 娴嬭瘯鏍戣〃Service涓氬姟灞傚鐞�
- *
- * @author Lion Li
- * @date 2021-07-26
- */
-// @DS("slave") // 鍒囨崲浠庡簱鏌ヨ
-@RequiredArgsConstructor
-@Service
-public class TestTreeServiceImpl implements ITestTreeService {
-
-    private final TestTreeMapper baseMapper;
-
-    @Override
-    public TestTreeVo queryById(Long id) {
-        return baseMapper.selectVoById(id);
-    }
-
-    // @DS("slave") // 鍒囨崲浠庡簱鏌ヨ
-    @Override
-    public List<TestTreeVo> queryList(TestTreeBo bo) {
-        LambdaQueryWrapper<TestTree> lqw = buildQueryWrapper(bo);
-        return baseMapper.selectVoList(lqw);
-    }
-
-    private LambdaQueryWrapper<TestTree> buildQueryWrapper(TestTreeBo bo) {
-        Map<String, Object> params = bo.getParams();
-        LambdaQueryWrapper<TestTree> lqw = Wrappers.lambdaQuery();
-        lqw.like(StringUtils.isNotBlank(bo.getTreeName()), TestTree::getTreeName, bo.getTreeName());
-        lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
-            TestTree::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime"));
-        return lqw;
-    }
-
-    @Override
-    public Boolean insertByBo(TestTreeBo bo) {
-        TestTree add = MapstructUtils.convert(bo, TestTree.class);
-        validEntityBeforeSave(add);
-        boolean flag = baseMapper.insert(add) > 0;
-        if (flag) {
-            bo.setId(add.getId());
-        }
-        return flag;
-    }
-
-    @Override
-    public Boolean updateByBo(TestTreeBo bo) {
-        TestTree update = MapstructUtils.convert(bo, TestTree.class);
-        validEntityBeforeSave(update);
-        return baseMapper.updateById(update) > 0;
-    }
-
-    /**
-     * 淇濆瓨鍓嶇殑鏁版嵁鏍¢獙
-     *
-     * @param entity 瀹炰綋绫绘暟鎹�
-     */
-    private void validEntityBeforeSave(TestTree entity) {
-        //TODO 鍋氫竴浜涙暟鎹牎楠�,濡傚敮涓�绾︽潫
-    }
-
-    @Override
-    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
-        if (isValid) {
-            //TODO 鍋氫竴浜涗笟鍔′笂鐨勬牎楠�,鍒ゆ柇鏄惁闇�瑕佹牎楠�
-        }
-        return baseMapper.deleteBatchIds(ids) > 0;
-    }
-}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/package-info.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/package-info.java
deleted file mode 100644
index 6060849..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package com.ruoyi.demo.service.impl;
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/service/package-info.java b/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/service/package-info.java
deleted file mode 100644
index d6a44c9..0000000
--- a/ruoyi-modules/ruoyi-demo/src/main/java/com/ruoyi/demo/service/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package com.ruoyi.demo.service;
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/MailController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/MailController.java
new file mode 100644
index 0000000..47b4349
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/MailController.java
@@ -0,0 +1,52 @@
+package org.dromara.demo.controller;
+
+import org.dromara.common.core.domain.R;
+import org.dromara.common.mail.utils.MailUtils;
+import lombok.RequiredArgsConstructor;
+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 java.io.File;
+
+
+/**
+ * 閭欢鍙戦�佹渚�
+ *
+ * @author Michelle.Chung
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/demo/mail")
+public class MailController {
+
+    /**
+     * 鍙戦�侀偖浠�
+     *
+     * @param to      鎺ユ敹浜�
+     * @param subject 鏍囬
+     * @param text    鍐呭
+     */
+    @GetMapping("/sendSimpleMessage")
+    public R<Void> sendSimpleMessage(String to, String subject, String text) {
+        MailUtils.sendText(to, subject, text);
+        return R.ok();
+    }
+
+    /**
+     * 鍙戦�侀偖浠讹紙甯﹂檮浠讹級
+     *
+     * @param to       鎺ユ敹浜�
+     * @param subject  鏍囬
+     * @param text     鍐呭
+     * @param filePath 闄勪欢璺緞
+     */
+    @GetMapping("/sendMessageWithAttachment")
+    public R<Void> sendMessageWithAttachment(String to, String subject, String text, String filePath) {
+        MailUtils.sendText(to, subject, text, new File(filePath));
+        return R.ok();
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisCacheController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisCacheController.java
new file mode 100644
index 0000000..341880c
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisCacheController.java
@@ -0,0 +1,95 @@
+package org.dromara.demo.controller;
+
+import org.dromara.common.core.constant.CacheNames;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.redis.utils.RedisUtils;
+import lombok.RequiredArgsConstructor;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.CachePut;
+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;
+
+import java.time.Duration;
+
+/**
+ * spring-cache 婕旂ず妗堜緥
+ *
+ * @author Lion Li
+ */
+// 绫荤骇鍒� 缂撳瓨缁熶竴閰嶇疆
+//@CacheConfig(cacheNames = CacheNames.DEMO_CACHE)
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/demo/cache")
+public class RedisCacheController {
+
+    /**
+     * 娴嬭瘯 @Cacheable
+     * <p>
+     * 琛ㄧず杩欎釜鏂规硶鏈変簡缂撳瓨鐨勫姛鑳�,鏂规硶鐨勮繑鍥炲�间細琚紦瀛樹笅鏉�
+     * 涓嬩竴娆¤皟鐢ㄨ鏂规硶鍓�,浼氬幓妫�鏌ユ槸鍚︾紦瀛樹腑宸茬粡鏈夊��
+     * 濡傛灉鏈夊氨鐩存帴杩斿洖,涓嶈皟鐢ㄦ柟娉�
+     * 濡傛灉娌℃湁,灏辫皟鐢ㄦ柟娉�,鐒跺悗鎶婄粨鏋滅紦瀛樿捣鏉�
+     * 杩欎釜娉ㄨВ銆屼竴鑸敤鍦ㄦ煡璇㈡柟娉曚笂銆�
+     * <p>
+     * 閲嶇偣璇存槑: 缂撳瓨娉ㄨВ涓ヨ皑涓庡叾浠栫瓫閫夋暟鎹姛鑳戒竴璧蜂娇鐢�
+     * 渚嬪: 鏁版嵁鏉冮檺娉ㄨВ 浼氶�犳垚 缂撳瓨鍑荤┛ 涓� 鏁版嵁涓嶄竴鑷撮棶棰�
+     * <p>
+     * cacheNames 鍛藉悕瑙勫垯 鏌ョ湅 {@link CacheNames} 娉ㄩ噴 鏀寔澶氬弬鏁�
+     */
+    @Cacheable(cacheNames = "demo:cache#60s#10m#20", key = "#key", condition = "#key != null")
+    @GetMapping("/test1")
+    public R<String> test1(String key, String value) {
+        return R.ok("鎿嶄綔鎴愬姛", value);
+    }
+
+    /**
+     * 娴嬭瘯 @CachePut
+     * <p>
+     * 鍔犱簡@CachePut娉ㄨВ鐨勬柟娉�,浼氭妸鏂规硶鐨勮繑鍥炲�紁ut鍒扮紦瀛橀噷闈㈢紦瀛樿捣鏉�,渚涘叾瀹冨湴鏂逛娇鐢�
+     * 瀹冦�岄�氬父鐢ㄥ湪鏂板鎴栬�呭疄鏃舵洿鏂版柟娉曚笂銆�
+     * <p>
+     * cacheNames 鍛藉悕瑙勫垯 鏌ョ湅 {@link CacheNames} 娉ㄩ噴 鏀寔澶氬弬鏁�
+     */
+    @CachePut(cacheNames = CacheNames.DEMO_CACHE, key = "#key", condition = "#key != null")
+    @GetMapping("/test2")
+    public R<String> test2(String key, String value) {
+        return R.ok("鎿嶄綔鎴愬姛", value);
+    }
+
+    /**
+     * 娴嬭瘯 @CacheEvict
+     * <p>
+     * 浣跨敤浜咰acheEvict娉ㄨВ鐨勬柟娉�,浼氭竻绌烘寚瀹氱紦瀛�
+     * 銆屼竴鑸敤鍦ㄥ垹闄ょ殑鏂规硶涓娿��
+     * <p>
+     * cacheNames 鍛藉悕瑙勫垯 鏌ョ湅 {@link CacheNames} 娉ㄩ噴 鏀寔澶氬弬鏁�
+     */
+    @CacheEvict(cacheNames = CacheNames.DEMO_CACHE, key = "#key", condition = "#key != null")
+    @GetMapping("/test3")
+    public R<String> test3(String key, String value) {
+        return R.ok("鎿嶄綔鎴愬姛", value);
+    }
+
+    /**
+     * 娴嬭瘯璁剧疆杩囨湡鏃堕棿
+     * 鎵嬪姩璁剧疆杩囨湡鏃堕棿10绉�
+     * 11绉掑悗鑾峰彇 鍒ゆ柇鏄惁鐩哥瓑
+     */
+    @GetMapping("/test6")
+    public R<Boolean> test6(String key, String value) {
+        RedisUtils.setCacheObject(key, value);
+        boolean flag = RedisUtils.expire(key, Duration.ofSeconds(10));
+        System.out.println("***********" + flag);
+        try {
+            Thread.sleep(11 * 1000);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+        Object obj = RedisUtils.getCacheObject(key);
+        return R.ok(value.equals(obj));
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisLockController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisLockController.java
new file mode 100644
index 0000000..b7e0962
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisLockController.java
@@ -0,0 +1,71 @@
+package org.dromara.demo.controller;
+
+import com.baomidou.lock.LockInfo;
+import com.baomidou.lock.LockTemplate;
+import com.baomidou.lock.annotation.Lock4j;
+import com.baomidou.lock.executor.RedissonLockExecutor;
+import org.dromara.common.core.domain.R;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.LocalTime;
+
+
+/**
+ * 娴嬭瘯鍒嗗竷寮忛攣鐨勬牱渚�
+ *
+ * @author shenxinquan
+ */
+@Slf4j
+@RestController
+@RequestMapping("/demo/redisLock")
+public class RedisLockController {
+
+    @Autowired
+    private LockTemplate lockTemplate;
+
+    /**
+     * 娴嬭瘯lock4j 娉ㄨВ
+     */
+    @Lock4j(keys = {"#key"})
+    @GetMapping("/testLock4j")
+    public R<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 R.ok("鎿嶄綔鎴愬姛", value);
+    }
+
+    /**
+     * 娴嬭瘯lock4j 宸ュ叿
+     */
+    @GetMapping("/testLock4jLockTemplate")
+    public R<String> testLock4jLockTemplate(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 R.ok("鎿嶄綔鎴愬姛", value);
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisPubSubController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisPubSubController.java
new file mode 100644
index 0000000..bdbf033
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisPubSubController.java
@@ -0,0 +1,47 @@
+package org.dromara.demo.controller;
+
+import org.dromara.common.core.domain.R;
+import org.dromara.common.redis.utils.RedisUtils;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * Redis 鍙戝竷璁㈤槄 婕旂ず妗堜緥
+ *
+ * @author Lion Li
+ */
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/demo/redis/pubsub")
+public class RedisPubSubController {
+
+    /**
+     * 鍙戝竷娑堟伅
+     *
+     * @param key   閫氶亾Key
+     * @param value 鍙戦�佸唴瀹�
+     */
+    @GetMapping("/pub")
+    public R<Void> pub(String key, String value) {
+        RedisUtils.publish(key, value, consumer -> {
+            System.out.println("鍙戝竷閫氶亾 => " + key + ", 鍙戦�佸�� => " + value);
+        });
+        return R.ok("鎿嶄綔鎴愬姛");
+    }
+
+    /**
+     * 璁㈤槄娑堟伅
+     *
+     * @param key 閫氶亾Key
+     */
+    @GetMapping("/sub")
+    public R<Void> sub(String key) {
+        RedisUtils.subscribe(key, String.class, msg -> {
+            System.out.println("璁㈤槄閫氶亾 => " + key + ", 鎺ユ敹鍊� => " + msg);
+        });
+        return R.ok("鎿嶄綔鎴愬姛");
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisRateLimiterController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisRateLimiterController.java
new file mode 100644
index 0000000..429c007
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisRateLimiterController.java
@@ -0,0 +1,52 @@
+package org.dromara.demo.controller;
+
+import org.dromara.common.core.domain.R;
+import org.dromara.common.ratelimiter.annotation.RateLimiter;
+import org.dromara.common.ratelimiter.enums.LimitType;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+/**
+ * 娴嬭瘯鍒嗗竷寮忛檺娴佹牱渚�
+ *
+ * @author Lion Li
+ */
+@Slf4j
+@RestController
+@RequestMapping("/demo/rateLimiter")
+public class RedisRateLimiterController {
+
+    /**
+     * 娴嬭瘯鍏ㄥ眬闄愭祦
+     * 鍏ㄥ眬褰卞搷
+     */
+    @RateLimiter(count = 2, time = 10)
+    @GetMapping("/test")
+    public R<String> test(String value) {
+        return R.ok("鎿嶄綔鎴愬姛", value);
+    }
+
+    /**
+     * 娴嬭瘯璇锋眰IP闄愭祦
+     * 鍚屼竴IP璇锋眰鍙楀奖鍝�
+     */
+    @RateLimiter(count = 2, time = 10, limitType = LimitType.IP)
+    @GetMapping("/testip")
+    public R<String> testip(String value) {
+        return R.ok("鎿嶄綔鎴愬姛", value);
+    }
+
+    /**
+     * 娴嬭瘯闆嗙兢瀹炰緥闄愭祦
+     * 鍚姩涓や釜鍚庣鏈嶅姟浜掍笉褰卞搷
+     */
+    @RateLimiter(count = 2, time = 10, limitType = LimitType.CLUSTER)
+    @GetMapping("/testcluster")
+    public R<String> testcluster(String value) {
+        return R.ok("鎿嶄綔鎴愬姛", value);
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/SmsController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/SmsController.java
new file mode 100644
index 0000000..e130cae
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/SmsController.java
@@ -0,0 +1,76 @@
+package org.dromara.demo.controller;
+
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.sms.config.properties.SmsProperties;
+import org.dromara.common.sms.core.SmsTemplate;
+import lombok.RequiredArgsConstructor;
+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 java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 鐭俊婕旂ず妗堜緥
+ * 璇峰厛闃呰鏂囨。 鍚﹀垯鏃犳硶浣跨敤
+ *
+ * @author Lion Li
+ * @version 4.2.0
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/demo/sms")
+public class SmsController {
+
+    private final SmsProperties smsProperties;
+//    private final SmsTemplate smsTemplate; // 鍙互浣跨敤spring娉ㄥ叆
+//    private final AliyunSmsTemplate smsTemplate; // 涔熷彲浠ユ敞鍏ユ煇涓巶瀹剁殑妯℃澘宸ュ叿
+
+    /**
+     * 鍙戦�佺煭淇liyun
+     *
+     * @param phones     鐢佃瘽鍙�
+     * @param templateId 妯℃澘ID
+     */
+    @GetMapping("/sendAliyun")
+    public R<Object> sendAliyun(String phones, String templateId) {
+        if (!smsProperties.getEnabled()) {
+            return R.fail("褰撳墠绯荤粺娌℃湁寮�鍚煭淇″姛鑳斤紒");
+        }
+        if (!SpringUtils.containsBean("aliyunSmsTemplate")) {
+            return R.fail("闃块噷浜戜緷璧栨湭寮曞叆锛�");
+        }
+        SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class);
+        Map<String, String> map = new HashMap<>(1);
+        map.put("code", "1234");
+        Object send = smsTemplate.send(phones, templateId, map);
+        return R.ok(send);
+    }
+
+    /**
+     * 鍙戦�佺煭淇encent
+     *
+     * @param phones     鐢佃瘽鍙�
+     * @param templateId 妯℃澘ID
+     */
+    @GetMapping("/sendTencent")
+    public R<Object> sendTencent(String phones, String templateId) {
+        if (!smsProperties.getEnabled()) {
+            return R.fail("褰撳墠绯荤粺娌℃湁寮�鍚煭淇″姛鑳斤紒");
+        }
+        if (!SpringUtils.containsBean("tencentSmsTemplate")) {
+            return R.fail("鑵捐浜戜緷璧栨湭寮曞叆锛�");
+        }
+        SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class);
+        Map<String, String> map = new HashMap<>(1);
+//        map.put("2", "娴嬭瘯娴嬭瘯");
+        map.put("1", "1234");
+        Object send = smsTemplate.send(phones, templateId, map);
+        return R.ok(send);
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/Swagger3DemoController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/Swagger3DemoController.java
new file mode 100644
index 0000000..bb02f98
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/Swagger3DemoController.java
@@ -0,0 +1,31 @@
+package org.dromara.demo.controller;
+
+import org.dromara.common.core.domain.R;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * swagger3 鐢ㄦ硶绀轰緥
+ *
+ * @author Lion Li
+ */
+@RestController
+@RequestMapping("/swagger/demo")
+public class Swagger3DemoController {
+
+    /**
+     * 涓婁紶璇锋眰
+     * 蹇呴』浣跨敤 @RequestPart 娉ㄨВ鏍囨敞涓烘枃浠�
+     *
+     * @param file 鏂囦欢
+     */
+    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+    public R<String> upload(@RequestPart("file") MultipartFile file) {
+        return R.ok("鎿嶄綔鎴愬姛", file.getOriginalFilename());
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestBatchController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestBatchController.java
new file mode 100644
index 0000000..af8c77b
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestBatchController.java
@@ -0,0 +1,90 @@
+package org.dromara.demo.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.demo.domain.TestDemo;
+import org.dromara.demo.mapper.TestDemoMapper;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 娴嬭瘯鎵归噺鏂规硶
+ *
+ * @author Lion Li
+ * @date 2021-05-30
+ */
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/demo/batch")
+public class TestBatchController extends BaseController {
+
+    /**
+     * 涓轰簡渚夸簬娴嬭瘯 鐩存帴寮曞叆mapper
+     */
+    private final TestDemoMapper testDemoMapper;
+
+    /**
+     * 鏂板鎵归噺鏂规硶 鍙畬缇庢浛浠� saveBatch 绉掔骇鎻掑叆涓婁竾鏁版嵁 (瀵筸ysql璐熻嵎杈冨ぇ)
+     * <p>
+     * 3.5.0 鐗堟湰 澧炲姞 rewriteBatchedStatements=true 鎵瑰鐞嗗弬鏁� 浣� MP 鍘熺敓鎵瑰鐞嗗彲浠ヨ揪鍒板悓鏍风殑閫熷害
+     */
+    @PostMapping("/add")
+//    @DS("slave")
+    public R<Void> add() {
+        List<TestDemo> list = new ArrayList<>();
+        for (int i = 0; i < 1000; i++) {
+            TestDemo testDemo = new TestDemo();
+            testDemo.setOrderNum(-1);
+            testDemo.setTestKey("鎵归噺鏂板");
+            testDemo.setValue("娴嬭瘯鏂板");
+            list.add(testDemo);
+        }
+        return toAjax(testDemoMapper.insertBatch(list));
+    }
+
+    /**
+     * 鏂板鎴栨洿鏂� 鍙畬缇庢浛浠� saveOrUpdateBatch 楂樻�ц兘
+     * <p>
+     * 3.5.0 鐗堟湰 澧炲姞 rewriteBatchedStatements=true 鎵瑰鐞嗗弬鏁� 浣� MP 鍘熺敓鎵瑰鐞嗗彲浠ヨ揪鍒板悓鏍风殑閫熷害
+     */
+    @PostMapping("/addOrUpdate")
+//    @DS("slave")
+    public R<Void> addOrUpdate() {
+        List<TestDemo> list = new ArrayList<>();
+        for (int i = 0; i < 1000; i++) {
+            TestDemo testDemo = new TestDemo();
+            testDemo.setOrderNum(-1);
+            testDemo.setTestKey("鎵归噺鏂板");
+            testDemo.setValue("娴嬭瘯鏂板");
+            list.add(testDemo);
+        }
+        testDemoMapper.insertBatch(list);
+        for (int i = 0; i < list.size(); i++) {
+            TestDemo testDemo = list.get(i);
+            testDemo.setTestKey("鎵归噺鏂板鎴栦慨鏀�");
+            testDemo.setValue("鎵归噺鏂板鎴栦慨鏀�");
+            if (i % 2 == 0) {
+                testDemo.setId(null);
+            }
+        }
+        return toAjax(testDemoMapper.insertOrUpdateBatch(list));
+    }
+
+    /**
+     * 鍒犻櫎鎵归噺鏂规硶
+     */
+    @DeleteMapping()
+//    @DS("slave")
+    public R<Void> remove() {
+        return toAjax(testDemoMapper.delete(new LambdaQueryWrapper<TestDemo>()
+            .eq(TestDemo::getOrderNum, -1L)));
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestDemoController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestDemoController.java
new file mode 100644
index 0000000..f31c540
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestDemoController.java
@@ -0,0 +1,147 @@
+package org.dromara.demo.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.ValidatorUtils;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.core.validate.QueryGroup;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.excel.core.ExcelResult;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.demo.domain.TestDemo;
+import org.dromara.demo.domain.bo.TestDemoBo;
+import org.dromara.demo.domain.bo.TestDemoImportVo;
+import org.dromara.demo.domain.vo.TestDemoVo;
+import org.dromara.demo.service.ITestDemoService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.MediaType;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 娴嬭瘯鍗曡〃Controller
+ *
+ * @author Lion Li
+ * @date 2021-07-26
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/demo/demo")
+public class TestDemoController extends BaseController {
+
+    private final ITestDemoService testDemoService;
+
+    /**
+     * 鏌ヨ娴嬭瘯鍗曡〃鍒楄〃
+     */
+    @SaCheckPermission("demo:demo:list")
+    @GetMapping("/list")
+    public TableDataInfo<TestDemoVo> list(@Validated(QueryGroup.class) TestDemoBo bo, PageQuery pageQuery) {
+        return testDemoService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 鑷畾涔夊垎椤垫煡璇�
+     */
+    @SaCheckPermission("demo:demo:list")
+    @GetMapping("/page")
+    public TableDataInfo<TestDemoVo> page(@Validated(QueryGroup.class) TestDemoBo bo, PageQuery pageQuery) {
+        return testDemoService.customPageList(bo, pageQuery);
+    }
+
+    /**
+     * 瀵煎叆鏁版嵁
+     *
+     * @param file 瀵煎叆鏂囦欢
+     */
+    @Log(title = "娴嬭瘯鍗曡〃", businessType = BusinessType.IMPORT)
+    @SaCheckPermission("demo:demo:import")
+    @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+    public R<Void> importData(@RequestPart("file") MultipartFile file) throws Exception {
+        ExcelResult<TestDemoImportVo> excelResult = ExcelUtil.importExcel(file.getInputStream(), TestDemoImportVo.class, true);
+        List<TestDemo> list = MapstructUtils.convert(excelResult.getList(), TestDemo.class);
+        testDemoService.saveBatch(list);
+        return R.ok(excelResult.getAnalysis());
+    }
+
+    /**
+     * 瀵煎嚭娴嬭瘯鍗曡〃鍒楄〃
+     */
+    @SaCheckPermission("demo:demo:export")
+    @Log(title = "娴嬭瘯鍗曡〃", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(@Validated TestDemoBo bo, HttpServletResponse response) {
+        List<TestDemoVo> list = testDemoService.queryList(bo);
+        // 娴嬭瘯闆姳id瀵煎嚭
+//        for (TestDemoVo vo : list) {
+//            vo.setId(1234567891234567893L);
+//        }
+        ExcelUtil.exportExcel(list, "娴嬭瘯鍗曡〃", TestDemoVo.class, response);
+    }
+
+    /**
+     * 鑾峰彇娴嬭瘯鍗曡〃璇︾粏淇℃伅
+     *
+     * @param id 娴嬭瘯ID
+     */
+    @SaCheckPermission("demo:demo:query")
+    @GetMapping("/{id}")
+    public R<TestDemoVo> getInfo(@NotNull(message = "涓婚敭涓嶈兘涓虹┖")
+                                 @PathVariable("id") Long id) {
+        return R.ok(testDemoService.queryById(id));
+    }
+
+    /**
+     * 鏂板娴嬭瘯鍗曡〃
+     */
+    @SaCheckPermission("demo:demo:add")
+    @Log(title = "娴嬭瘯鍗曡〃", businessType = BusinessType.INSERT)
+    @RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS, message = "{repeat.submit.message}")
+    @PostMapping()
+    public R<Void> add(@RequestBody TestDemoBo bo) {
+        // 浣跨敤鏍¢獙宸ュ叿瀵规爣 @Validated(AddGroup.class) 娉ㄨВ
+        // 鐢ㄤ簬鍦ㄩ潪 Controller 鐨勫湴鏂规牎楠屽璞�
+        ValidatorUtils.validate(bo, AddGroup.class);
+        return toAjax(testDemoService.insertByBo(bo));
+    }
+
+    /**
+     * 淇敼娴嬭瘯鍗曡〃
+     */
+    @SaCheckPermission("demo:demo:edit")
+    @Log(title = "娴嬭瘯鍗曡〃", businessType = BusinessType.UPDATE)
+    @RepeatSubmit
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody TestDemoBo bo) {
+        return toAjax(testDemoService.updateByBo(bo));
+    }
+
+    /**
+     * 鍒犻櫎娴嬭瘯鍗曡〃
+     *
+     * @param ids 娴嬭瘯ID涓�
+     */
+    @SaCheckPermission("demo:demo:remove")
+    @Log(title = "娴嬭瘯鍗曡〃", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
+                          @PathVariable Long[] ids) {
+        return toAjax(testDemoService.deleteWithValidByIds(Arrays.asList(ids), true));
+    }
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestEncryptController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestEncryptController.java
new file mode 100644
index 0000000..2b6886d
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestEncryptController.java
@@ -0,0 +1,55 @@
+package org.dromara.demo.controller;
+
+import org.dromara.common.core.domain.R;
+import org.dromara.demo.domain.TestDemoEncrypt;
+import org.dromara.demo.mapper.TestDemoEncryptMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+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 java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * 娴嬭瘯鏁版嵁搴撳姞瑙e瘑鍔熻兘
+ *
+ * @author Lion Li
+ */
+@Validated
+@RestController
+@RequestMapping("/demo/encrypt")
+public class TestEncryptController {
+
+    @Autowired
+    private TestDemoEncryptMapper mapper;
+    @Value("${mybatis-encryptor.enable}")
+    private Boolean encryptEnable;
+
+    /**
+     * 娴嬭瘯鏁版嵁搴撳姞瑙e瘑
+     *
+     * @param key   娴嬭瘯key
+     * @param value 娴嬭瘯value
+     */
+    @GetMapping()
+    public R<Map<String, TestDemoEncrypt>> test(String key, String value) {
+        if (!encryptEnable) {
+            throw new RuntimeException("鍔犲瘑鍔熻兘鏈紑鍚�!");
+        }
+        Map<String, TestDemoEncrypt> map = new HashMap<>(2);
+        TestDemoEncrypt demo = new TestDemoEncrypt();
+        demo.setTestKey(key);
+        demo.setValue(value);
+        mapper.insert(demo);
+        map.put("鍔犲瘑", demo);
+        TestDemoEncrypt testDemo = mapper.selectById(demo.getId());
+        map.put("瑙e瘑", testDemo);
+        return R.ok(map);
+    }
+
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestExcelController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestExcelController.java
new file mode 100644
index 0000000..d83455d
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestExcelController.java
@@ -0,0 +1,97 @@
+package org.dromara.demo.controller;
+
+import cn.hutool.core.collection.CollUtil;
+import org.dromara.common.excel.utils.ExcelUtil;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import jakarta.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 娴嬭瘯Excel鍔熻兘
+ *
+ * @author Lion Li
+ */
+@RestController
+@RequestMapping("/demo/excel")
+public class TestExcelController {
+
+    /**
+     * 鍗曞垪琛ㄥ鏁版嵁
+     */
+    @GetMapping("/exportTemplateOne")
+    public void exportTemplateOne(HttpServletResponse response) {
+        Map<String, String> map = new HashMap<>();
+        map.put("title", "鍗曞垪琛ㄥ鏁版嵁");
+        map.put("test1", "鏁版嵁娴嬭瘯1");
+        map.put("test2", "鏁版嵁娴嬭瘯2");
+        map.put("test3", "鏁版嵁娴嬭瘯3");
+        map.put("test4", "鏁版嵁娴嬭瘯4");
+        map.put("testTest", "666");
+        List<TestObj> list = new ArrayList<>();
+        list.add(new TestObj("鍗曞垪琛ㄦ祴璇�1", "鍒楄〃娴嬭瘯1", "鍒楄〃娴嬭瘯2", "鍒楄〃娴嬭瘯3", "鍒楄〃娴嬭瘯4"));
+        list.add(new TestObj("鍗曞垪琛ㄦ祴璇�2", "鍒楄〃娴嬭瘯5", "鍒楄〃娴嬭瘯6", "鍒楄〃娴嬭瘯7", "鍒楄〃娴嬭瘯8"));
+        list.add(new TestObj("鍗曞垪琛ㄦ祴璇�3", "鍒楄〃娴嬭瘯9", "鍒楄〃娴嬭瘯10", "鍒楄〃娴嬭瘯11", "鍒楄〃娴嬭瘯12"));
+        ExcelUtil.exportTemplate(CollUtil.newArrayList(map, list), "鍗曞垪琛�.xlsx", "excel/鍗曞垪琛�.xlsx", response);
+    }
+
+    /**
+     * 澶氬垪琛ㄥ鏁版嵁
+     */
+    @GetMapping("/exportTemplateMuliti")
+    public void exportTemplateMuliti(HttpServletResponse response) {
+        Map<String, String> map = new HashMap<>();
+        map.put("title1", "鏍囬1");
+        map.put("title2", "鏍囬2");
+        map.put("title3", "鏍囬3");
+        map.put("title4", "鏍囬4");
+        map.put("author", "Lion Li");
+        List<TestObj1> list1 = new ArrayList<>();
+        list1.add(new TestObj1("list1娴嬭瘯1", "list1娴嬭瘯2", "list1娴嬭瘯3"));
+        list1.add(new TestObj1("list1娴嬭瘯4", "list1娴嬭瘯5", "list1娴嬭瘯6"));
+        list1.add(new TestObj1("list1娴嬭瘯7", "list1娴嬭瘯8", "list1娴嬭瘯9"));
+        List<TestObj1> list2 = new ArrayList<>();
+        list2.add(new TestObj1("list2娴嬭瘯1", "list2娴嬭瘯2", "list2娴嬭瘯3"));
+        list2.add(new TestObj1("list2娴嬭瘯4", "list2娴嬭瘯5", "list2娴嬭瘯6"));
+        List<TestObj1> list3 = new ArrayList<>();
+        list3.add(new TestObj1("list3娴嬭瘯1", "list3娴嬭瘯2", "list3娴嬭瘯3"));
+        List<TestObj1> list4 = new ArrayList<>();
+        list4.add(new TestObj1("list4娴嬭瘯1", "list4娴嬭瘯2", "list4娴嬭瘯3"));
+        list4.add(new TestObj1("list4娴嬭瘯4", "list4娴嬭瘯5", "list4娴嬭瘯6"));
+        list4.add(new TestObj1("list4娴嬭瘯7", "list4娴嬭瘯8", "list4娴嬭瘯9"));
+        list4.add(new TestObj1("list4娴嬭瘯10", "list4娴嬭瘯11", "list4娴嬭瘯12"));
+        Map<String, Object> multiListMap = new HashMap<>();
+        multiListMap.put("map", map);
+        multiListMap.put("data1", list1);
+        multiListMap.put("data2", list2);
+        multiListMap.put("data3", list3);
+        multiListMap.put("data4", list4);
+        ExcelUtil.exportTemplateMultiList(multiListMap, "澶氬垪琛�.xlsx", "excel/澶氬垪琛�.xlsx", response);
+    }
+
+    @Data
+    @AllArgsConstructor
+    static class TestObj1 {
+        private String test1;
+        private String test2;
+        private String test3;
+    }
+
+    @Data
+    @AllArgsConstructor
+    static class TestObj {
+        private String name;
+        private String list1;
+        private String list2;
+        private String list3;
+        private String list4;
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestI18nController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestI18nController.java
new file mode 100644
index 0000000..40393c5
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestI18nController.java
@@ -0,0 +1,71 @@
+package org.dromara.demo.controller;
+
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.utils.MessageUtils;
+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 jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+
+
+/**
+ * 娴嬭瘯鍥介檯鍖�
+ *
+ * @author Lion Li
+ */
+@Validated
+@RestController
+@RequestMapping("/demo/i18n")
+public class TestI18nController {
+
+    /**
+     * 閫氳繃code鑾峰彇鍥介檯鍖栧唴瀹�
+     * code涓� messages.properties 涓殑 key
+     * <p>
+     * 娴嬭瘯浣跨敤 user.register.success
+     *
+     * @param code 鍥介檯鍖朿ode
+     */
+    @GetMapping()
+    public R<Void> get(String code) {
+        return R.ok(MessageUtils.message(code));
+    }
+
+    /**
+     * Validator 鏍¢獙鍥介檯鍖�
+     * 涓嶄紶鍊� 鍒嗗埆鏌ョ湅寮傚父杩斿洖
+     * <p>
+     * 娴嬭瘯浣跨敤 not.null
+     */
+    @GetMapping("/test1")
+    public R<Void> test1(@NotBlank(message = "{not.null}") String str) {
+        return R.ok(str);
+    }
+
+    /**
+     * Bean 鏍¢獙鍥介檯鍖�
+     * 涓嶄紶鍊� 鍒嗗埆鏌ョ湅寮傚父杩斿洖
+     * <p>
+     * 娴嬭瘯浣跨敤 not.null
+     */
+    @GetMapping("/test2")
+    public R<TestI18nBo> test2(@Validated TestI18nBo bo) {
+        return R.ok(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-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestSensitiveController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestSensitiveController.java
new file mode 100644
index 0000000..8d6ad53
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestSensitiveController.java
@@ -0,0 +1,76 @@
+package org.dromara.demo.controller;
+
+import org.dromara.common.core.domain.R;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.sensitive.annotation.Sensitive;
+import org.dromara.common.sensitive.core.SensitiveStrategy;
+import lombok.Data;
+import org.dromara.common.sensitive.core.SensitiveService;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 娴嬭瘯鏁版嵁鑴辨晱鎺у埗鍣�
+ * <p>
+ * 榛樿绠$悊鍛樹笉杩囨护
+ * 闇�鑷鏍规嵁涓氬姟閲嶅啓瀹炵幇
+ *
+ * @author Lion Li
+ * @version 3.6.0
+ * @see SensitiveService
+ */
+@RestController
+@RequestMapping("/demo/sensitive")
+public class TestSensitiveController extends BaseController {
+
+    /**
+     * 娴嬭瘯鏁版嵁鑴辨晱
+     */
+    @GetMapping("/test")
+    public R<TestSensitive> test() {
+        TestSensitive testSensitive = new TestSensitive();
+        testSensitive.setIdCard("210397198608215431");
+        testSensitive.setPhone("17640125371");
+        testSensitive.setAddress("鍖椾含甯傛湞闃冲尯鏌愭煇鍥涘悎闄�1203瀹�");
+        testSensitive.setEmail("17640125371@163.com");
+        testSensitive.setBankCard("6226456952351452853");
+        return R.ok(testSensitive);
+    }
+
+    @Data
+    static class TestSensitive {
+
+        /**
+         * 韬唤璇�
+         */
+        @Sensitive(strategy = SensitiveStrategy.ID_CARD)
+        private String idCard;
+
+        /**
+         * 鐢佃瘽
+         */
+        @Sensitive(strategy = SensitiveStrategy.PHONE)
+        private String phone;
+
+        /**
+         * 鍦板潃
+         */
+        @Sensitive(strategy = SensitiveStrategy.ADDRESS)
+        private String address;
+
+        /**
+         * 閭
+         */
+        @Sensitive(strategy = SensitiveStrategy.EMAIL)
+        private String email;
+
+        /**
+         * 閾惰鍗�
+         */
+        @Sensitive(strategy = SensitiveStrategy.BANK_CARD)
+        private String bankCard;
+
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestTreeController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestTreeController.java
new file mode 100644
index 0000000..5c55205
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestTreeController.java
@@ -0,0 +1,107 @@
+package org.dromara.demo.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.core.validate.QueryGroup;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.demo.domain.bo.TestTreeBo;
+import org.dromara.demo.domain.vo.TestTreeVo;
+import org.dromara.demo.service.ITestTreeService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 娴嬭瘯鏍戣〃Controller
+ *
+ * @author Lion Li
+ * @date 2021-07-26
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/demo/tree")
+public class TestTreeController extends BaseController {
+
+    private final ITestTreeService testTreeService;
+
+    /**
+     * 鏌ヨ娴嬭瘯鏍戣〃鍒楄〃
+     */
+    @SaCheckPermission("demo:tree:list")
+    @GetMapping("/list")
+    public R<List<TestTreeVo>> list(@Validated(QueryGroup.class) TestTreeBo bo) {
+        List<TestTreeVo> list = testTreeService.queryList(bo);
+        return R.ok(list);
+    }
+
+    /**
+     * 瀵煎嚭娴嬭瘯鏍戣〃鍒楄〃
+     */
+    @SaCheckPermission("demo:tree:export")
+    @Log(title = "娴嬭瘯鏍戣〃", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public void export(@Validated TestTreeBo bo, HttpServletResponse response) {
+        List<TestTreeVo> list = testTreeService.queryList(bo);
+        ExcelUtil.exportExcel(list, "娴嬭瘯鏍戣〃", TestTreeVo.class, response);
+    }
+
+    /**
+     * 鑾峰彇娴嬭瘯鏍戣〃璇︾粏淇℃伅
+     *
+     * @param id 娴嬭瘯鏍慖D
+     */
+    @SaCheckPermission("demo:tree:query")
+    @GetMapping("/{id}")
+    public R<TestTreeVo> getInfo(@NotNull(message = "涓婚敭涓嶈兘涓虹┖")
+                                 @PathVariable("id") Long id) {
+        return R.ok(testTreeService.queryById(id));
+    }
+
+    /**
+     * 鏂板娴嬭瘯鏍戣〃
+     */
+    @SaCheckPermission("demo:tree:add")
+    @Log(title = "娴嬭瘯鏍戣〃", businessType = BusinessType.INSERT)
+    @RepeatSubmit
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody TestTreeBo bo) {
+        return toAjax(testTreeService.insertByBo(bo));
+    }
+
+    /**
+     * 淇敼娴嬭瘯鏍戣〃
+     */
+    @SaCheckPermission("demo:tree:edit")
+    @Log(title = "娴嬭瘯鏍戣〃", businessType = BusinessType.UPDATE)
+    @RepeatSubmit
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody TestTreeBo bo) {
+        return toAjax(testTreeService.updateByBo(bo));
+    }
+
+    /**
+     * 鍒犻櫎娴嬭瘯鏍戣〃
+     *
+     * @param ids 娴嬭瘯鏍慖D涓�
+     */
+    @SaCheckPermission("demo:tree:remove")
+    @Log(title = "娴嬭瘯鏍戣〃", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
+                          @PathVariable Long[] ids) {
+        return toAjax(testTreeService.deleteWithValidByIds(Arrays.asList(ids), true));
+    }
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/WeSocketController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/WeSocketController.java
new file mode 100644
index 0000000..699a5e6
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/WeSocketController.java
@@ -0,0 +1,33 @@
+package org.dromara.demo.controller;
+
+import org.dromara.common.core.domain.R;
+import org.dromara.common.websocket.dto.WebSocketMessageDto;
+import org.dromara.common.websocket.utils.WebSocketUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * WebSocket 婕旂ず妗堜緥
+ *
+ * @author zendwang
+ */
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/demo/websocket")
+@Slf4j
+public class WeSocketController {
+
+    /**
+     * 鍙戝竷娑堟伅
+     *
+     * @param dto 鍙戦�佸唴瀹�
+     */
+    @GetMapping("/send")
+    public R<Void> send(WebSocketMessageDto dto) throws InterruptedException {
+        WebSocketUtils.publishMessage(dto);
+        return R.ok("鎿嶄綔鎴愬姛");
+    }
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/package-info.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/package-info.java
new file mode 100644
index 0000000..16c30f8
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/package-info.java
@@ -0,0 +1 @@
+package org.dromara.demo.controller;
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/queue/BoundedQueueController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/queue/BoundedQueueController.java
new file mode 100644
index 0000000..b105ae9
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/queue/BoundedQueueController.java
@@ -0,0 +1,90 @@
+package org.dromara.demo.controller.queue;
+
+import org.dromara.common.core.domain.R;
+import org.dromara.common.redis.utils.QueueUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 鏈夌晫闃熷垪 婕旂ず妗堜緥
+ * <p>
+ * 杞婚噺绾ч槦鍒� 閲嶉噺绾ф暟鎹噺 璇蜂娇鐢� MQ
+ * <p>
+ * 闆嗙兢娴嬭瘯閫氳繃 鍚屼竴涓暟鎹彧浼氳娑堣垂涓�娆� 鍋氬ソ浜嬪姟琛ュ伩
+ * 闆嗙兢娴嬭瘯娴佺▼ 鍦ㄥ叾涓竴鍙板彂閫佹暟鎹� 涓ょ鍒嗗埆璋冪敤鑾峰彇鎺ュ彛 涓�娆¤幏鍙栦竴鏉�
+ *
+ * @author Lion Li
+ * @version 3.6.0
+ */
+@Slf4j
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/demo/queue/bounded")
+public class BoundedQueueController {
+
+
+    /**
+     * 娣诲姞闃熷垪鏁版嵁
+     *
+     * @param queueName 闃熷垪鍚�
+     * @param capacity  瀹归噺
+     */
+    @GetMapping("/add")
+    public R<Void> add(String queueName, int capacity) {
+        // 鐢ㄥ畬浜嗕竴瀹氳閿�姣� 鍚﹀垯浼氫竴鐩村瓨鍦�
+        boolean b = QueueUtils.destroyQueue(queueName);
+        log.info("閫氶亾: {} , 鍒犻櫎: {}", queueName, b);
+        // 鍒濆鍖栬缃竴娆″嵆鍙�
+        if (QueueUtils.trySetBoundedQueueCapacity(queueName, capacity)) {
+            log.info("閫氶亾: {} , 璁剧疆瀹归噺: {}", queueName, capacity);
+        } else {
+            log.info("閫氶亾: {} , 璁剧疆瀹归噺澶辫触", queueName);
+            return R.fail("鎿嶄綔澶辫触");
+        }
+        for (int i = 0; i < 11; i++) {
+            String data = "data-" + i;
+            boolean flag = QueueUtils.addBoundedQueueObject(queueName, data);
+            if (flag == false) {
+                log.info("閫氶亾: {} , 鍙戦�佹暟鎹�: {} 澶辫触, 閫氶亾宸叉弧", queueName, data);
+            } else {
+                log.info("閫氶亾: {} , 鍙戦�佹暟鎹�: {}", queueName, data);
+            }
+        }
+        return R.ok("鎿嶄綔鎴愬姛");
+    }
+
+    /**
+     * 鍒犻櫎闃熷垪鏁版嵁
+     *
+     * @param queueName 闃熷垪鍚�
+     */
+    @GetMapping("/remove")
+    public R<Void> remove(String queueName) {
+        String data = "data-" + 5;
+        if (QueueUtils.removeQueueObject(queueName, data)) {
+            log.info("閫氶亾: {} , 鍒犻櫎鏁版嵁: {}", queueName, data);
+        } else {
+            return R.fail("鎿嶄綔澶辫触");
+        }
+        return R.ok("鎿嶄綔鎴愬姛");
+    }
+
+    /**
+     * 鑾峰彇闃熷垪鏁版嵁
+     *
+     * @param queueName 闃熷垪鍚�
+     */
+    @GetMapping("/get")
+    public R<Void> get(String queueName) {
+        String data;
+        do {
+            data = QueueUtils.getQueueObject(queueName);
+            log.info("閫氶亾: {} , 鑾峰彇鏁版嵁: {}", queueName, data);
+        } while (data != null);
+        return R.ok("鎿嶄綔鎴愬姛");
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/queue/DelayedQueueController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/queue/DelayedQueueController.java
new file mode 100644
index 0000000..f9b81c1
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/queue/DelayedQueueController.java
@@ -0,0 +1,90 @@
+package org.dromara.demo.controller.queue;
+
+import org.dromara.common.core.domain.R;
+import org.dromara.common.redis.utils.QueueUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 寤惰繜闃熷垪 婕旂ず妗堜緥
+ * <p>
+ * 杞婚噺绾ч槦鍒� 閲嶉噺绾ф暟鎹噺 璇蜂娇鐢� MQ
+ * 渚嬪: 鍒涘缓璁㈠崟30鍒嗛挓鍚庤繃鏈熷鐞�
+ * <p>
+ * 闆嗙兢娴嬭瘯閫氳繃 鍚屼竴涓暟鎹彧浼氳娑堣垂涓�娆� 鍋氬ソ浜嬪姟琛ュ伩
+ * 闆嗙兢娴嬭瘯娴佺▼ 涓ゅ彴闆嗙兢鍒嗗埆寮�鍚闃� 鍦ㄥ叾涓竴鍙板彂閫佹暟鎹� 瑙傚療鎺ユ敹娑堟伅鐨勮寰�
+ *
+ * @author Lion Li
+ * @version 3.6.0
+ */
+@Slf4j
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/demo/queue/delayed")
+public class DelayedQueueController {
+
+    /**
+     * 璁㈤槄闃熷垪
+     *
+     * @param queueName 闃熷垪鍚�
+     */
+    @GetMapping("/subscribe")
+    public R<Void> subscribe(String queueName) {
+        log.info("閫氶亾: {} 鐩戝惉涓�......", queueName);
+        // 椤圭洰鍒濆鍖栬缃竴娆″嵆鍙�
+        QueueUtils.subscribeBlockingQueue(queueName, (String orderNum) -> {
+            // 瑙傚療鎺ユ敹鏃堕棿
+            log.info("閫氶亾: {}, 鏀跺埌鏁版嵁: {}", queueName, orderNum);
+        });
+        return R.ok("鎿嶄綔鎴愬姛");
+    }
+
+    /**
+     * 娣诲姞闃熷垪鏁版嵁
+     *
+     * @param queueName 闃熷垪鍚�
+     * @param orderNum  璁㈠崟鍙�
+     * @param time      寤惰繜鏃堕棿(绉�)
+     */
+    @GetMapping("/add")
+    public R<Void> add(String queueName, String orderNum, Long time) {
+        QueueUtils.addDelayedQueueObject(queueName, orderNum, time, TimeUnit.SECONDS);
+        // 瑙傚療鍙戦�佹椂闂�
+        log.info("閫氶亾: {} , 鍙戦�佹暟鎹�: {}", queueName, orderNum);
+        return R.ok("鎿嶄綔鎴愬姛");
+    }
+
+    /**
+     * 鍒犻櫎闃熷垪鏁版嵁
+     *
+     * @param queueName 闃熷垪鍚�
+     * @param orderNum  璁㈠崟鍙�
+     */
+    @GetMapping("/remove")
+    public R<Void> remove(String queueName, String orderNum) {
+        if (QueueUtils.removeDelayedQueueObject(queueName, orderNum)) {
+            log.info("閫氶亾: {} , 鍒犻櫎鏁版嵁: {}", queueName, orderNum);
+        } else {
+            return R.fail("鎿嶄綔澶辫触");
+        }
+        return R.ok("鎿嶄綔鎴愬姛");
+    }
+
+    /**
+     * 閿�姣侀槦鍒�
+     *
+     * @param queueName 闃熷垪鍚�
+     */
+    @GetMapping("/destroy")
+    public R<Void> destroy(String queueName) {
+        // 鐢ㄥ畬浜嗕竴瀹氳閿�姣� 鍚﹀垯浼氫竴鐩村瓨鍦�
+        QueueUtils.destroyDelayedQueue(queueName);
+        return R.ok("鎿嶄綔鎴愬姛");
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/queue/PriorityDemo.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/queue/PriorityDemo.java
new file mode 100644
index 0000000..e2449b5
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/queue/PriorityDemo.java
@@ -0,0 +1,22 @@
+package org.dromara.demo.controller.queue;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 瀹炰綋绫� 娉ㄦ剰涓嶅厑璁镐娇鐢ㄥ唴閮ㄧ被 鍚﹀垯浼氭壘涓嶅埌绫�
+ *
+ * @author Lion Li
+ * @version 3.6.0
+ */
+@Data
+@NoArgsConstructor
+public class PriorityDemo implements Comparable<PriorityDemo> {
+    private String name;
+    private Integer orderNum;
+
+    @Override
+    public int compareTo(PriorityDemo other) {
+        return Integer.compare(getOrderNum(), other.getOrderNum());
+    }
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/queue/PriorityQueueController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/queue/PriorityQueueController.java
new file mode 100644
index 0000000..1989d9e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/queue/PriorityQueueController.java
@@ -0,0 +1,89 @@
+package org.dromara.demo.controller.queue;
+
+import cn.hutool.core.util.RandomUtil;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.redis.utils.QueueUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 浼樺厛闃熷垪 婕旂ず妗堜緥
+ * <p>
+ * 杞婚噺绾ч槦鍒� 閲嶉噺绾ф暟鎹噺 璇蜂娇鐢� MQ
+ * <p>
+ * 闆嗙兢娴嬭瘯閫氳繃 鍚屼竴涓秷鎭彧浼氳娑堣垂涓�娆� 鍋氬ソ浜嬪姟琛ュ伩
+ * 闆嗙兢娴嬭瘯娴佺▼ 鍦ㄥ叾涓竴鍙板彂閫佹暟鎹� 涓ょ鍒嗗埆璋冪敤鑾峰彇鎺ュ彛 涓�娆¤幏鍙栦竴鏉�
+ *
+ * @author Lion Li
+ * @version 3.6.0
+ */
+@Slf4j
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/demo/queue/priority")
+public class PriorityQueueController {
+
+    /**
+     * 娣诲姞闃熷垪鏁版嵁
+     *
+     * @param queueName 闃熷垪鍚�
+     */
+    @GetMapping("/add")
+    public R<Void> add(String queueName) {
+        // 鐢ㄥ畬浜嗕竴瀹氳閿�姣� 鍚﹀垯浼氫竴鐩村瓨鍦�
+        boolean b = QueueUtils.destroyQueue(queueName);
+        log.info("閫氶亾: {} , 鍒犻櫎: {}", queueName, b);
+
+        for (int i = 0; i < 10; i++) {
+            int randomNum = RandomUtil.randomInt(10);
+            PriorityDemo data = new PriorityDemo();
+            data.setName("data-" + i);
+            data.setOrderNum(randomNum);
+            if (QueueUtils.addPriorityQueueObject(queueName, data)) {
+                log.info("閫氶亾: {} , 鍙戦�佹暟鎹�: {}", queueName, data);
+            } else {
+                log.info("閫氶亾: {} , 鍙戦�佹暟鎹�: {}, 鍙戦�佸け璐�", queueName, data);
+            }
+        }
+        return R.ok("鎿嶄綔鎴愬姛");
+    }
+
+    /**
+     * 鍒犻櫎闃熷垪鏁版嵁
+     *
+     * @param queueName 闃熷垪鍚�
+     * @param name      瀵硅薄鍚�
+     * @param orderNum  鎺掑簭鍙�
+     */
+    @GetMapping("/remove")
+    public R<Void> remove(String queueName, String name, Integer orderNum) {
+        PriorityDemo data = new PriorityDemo();
+        data.setName(name);
+        data.setOrderNum(orderNum);
+        if (QueueUtils.removeQueueObject(queueName, data)) {
+            log.info("閫氶亾: {} , 鍒犻櫎鏁版嵁: {}", queueName, data);
+        } else {
+            return R.fail("鎿嶄綔澶辫触");
+        }
+        return R.ok("鎿嶄綔鎴愬姛");
+    }
+
+    /**
+     * 鑾峰彇闃熷垪鏁版嵁
+     *
+     * @param queueName 闃熷垪鍚�
+     */
+    @GetMapping("/get")
+    public R<Void> get(String queueName) {
+        PriorityDemo data;
+        do {
+            data = QueueUtils.getQueueObject(queueName);
+            log.info("閫氶亾: {} , 鑾峰彇鏁版嵁: {}", queueName, data);
+        } while (data != null);
+        return R.ok("鎿嶄綔鎴愬姛");
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/TestDemo.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/TestDemo.java
new file mode 100644
index 0000000..d3af0c9
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/TestDemo.java
@@ -0,0 +1,68 @@
+package org.dromara.demo.domain;
+
+import com.baomidou.mybatisplus.annotation.*;
+import org.dromara.common.tenant.core.TenantEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 娴嬭瘯鍗曡〃瀵硅薄 test_demo
+ *
+ * @author Lion Li
+ * @date 2021-07-26
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("test_demo")
+public class TestDemo extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 涓婚敭
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 閮ㄩ棬id
+     */
+    private Long deptId;
+
+    /**
+     * 鐢ㄦ埛id
+     */
+    private Long userId;
+
+    /**
+     * 鎺掑簭鍙�
+     */
+    @OrderBy(asc = false, sort = 1)
+    private Integer orderNum;
+
+    /**
+     * key閿�
+     */
+    private String testKey;
+
+    /**
+     * 鍊�
+     */
+    private String value;
+
+    /**
+     * 鐗堟湰
+     */
+    @Version
+    private Long version;
+
+    /**
+     * 鍒犻櫎鏍囧織
+     */
+    @TableLogic
+    private Long delFlag;
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/TestDemoEncrypt.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/TestDemoEncrypt.java
new file mode 100644
index 0000000..bdcd596
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/TestDemoEncrypt.java
@@ -0,0 +1,29 @@
+package org.dromara.demo.domain;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import org.dromara.common.encrypt.annotation.EncryptField;
+import org.dromara.common.encrypt.enumd.AlgorithmType;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("test_demo")
+public class TestDemoEncrypt extends TestDemo {
+
+    /**
+     * key閿�
+     */
+    // @EncryptField(algorithm=AlgorithmType.SM2, privateKey = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgZSlOvw8FBiH+aFJWLYZP/VRjg9wjfRarTkGBZd/T3N+gCgYIKoEcz1UBgi2hRANCAAR5DGuQwJqkxnbCsP+iPSDoHWIF4RwcR5EsSvT8QPxO1wRkR2IhCkzvRb32x2CUgJFdvoqVqfApFDPZzShqzBwX", publicKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEeQxrkMCapMZ2wrD/oj0g6B1iBeEcHEeRLEr0/ED8TtcEZEdiIQpM70W99sdglICRXb6KlanwKRQz2c0oaswcFw==")
+    @EncryptField(algorithm = AlgorithmType.RSA, privateKey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBANBBEeueWlXlkkj2+WY5l+IWe42d8b5K28g+G/CFKC/yYAEHtqGlCsBOrb+YBkG9mPzmuYA/n9k0NFIc8E8yY5vZQaroyFBrTTWEzG9RY2f7Y3svVyybs6jpXSUs4xff8abo7wL1Y/wUaeatTViamxYnyTvdTmLm3d+JjRij68rxAgMBAAECgYAB0TnhXraSopwIVRfmboea1b0upl+BUdTJcmci412UjrKr5aE695ZLPkXbFXijVu7HJlyyv94NVUdaMACV7Ku/S2RuNB70M7YJm8rAjHFC3/i2ZeIM60h1Ziy4QKv0XM3pRATlDCDNhC1WUrtQCQSgU8kcp6eUUppruOqDzcY04QJBAPm9+sBP9CwDRgy3e5+V8aZtJkwDstb0lVVV/KY890cydVxiCwvX3fqVnxKMlb+x0YtH0sb9v+71xvK2lGobaRECQQDVePU6r/cCEfpc+nkWF6osAH1f8Mux3rYv2DoBGvaPzV2BGfsLed4neRfCwWNCKvGPCdW+L0xMJg8+RwaoBUPhAkAT5kViqXxFPYWJYd1h2+rDXhMdH3ZSlm6HvDBDdrwlWinr0Iwcx3iSjPV93uHXwm118aUj4fg3LDJMCKxOwBxhAkByrQXfvwOMYygBprRBf/j0plazoWFrbd6lGR0f1uI5IfNnFRPdeFw1DEINZ2Hw+6zEUF44SqRMC+4IYJNc02dBAkBCgy7RvfyV/A7N6kKXxTHauY0v6XwSSvpeKtRJkbIcRWOdIYvaHO9L7cklj3vIEdwjSUp9K4VTBYYlmAz1xh03", publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQQRHrnlpV5ZJI9vlmOZfiFnuNnfG+StvIPhvwhSgv8mABB7ahpQrATq2/mAZBvZj85rmAP5/ZNDRSHPBPMmOb2UGq6MhQa001hMxvUWNn+2N7L1csm7Oo6V0lLOMX3/Gm6O8C9WP8FGnmrU1YmpsWJ8k73U5i5t3fiY0Yo+vK8QIDAQAB")
+    private String testKey;
+
+    /**
+     * 鍊�
+     */
+    // @EncryptField // 浠�涔堜篃涓嶅啓璧伴粯璁ml閰嶇疆
+    // @EncryptField(algorithm = AlgorithmType.SM4, password = "10rfylhtccpuyke5")
+    @EncryptField(algorithm = AlgorithmType.AES, password = "10rfylhtccpuyke5")
+    private String value;
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/TestTree.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/TestTree.java
new file mode 100644
index 0000000..fd68253
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/TestTree.java
@@ -0,0 +1,65 @@
+package org.dromara.demo.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.Version;
+import org.dromara.common.tenant.core.TenantEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 娴嬭瘯鏍戣〃瀵硅薄 test_tree
+ *
+ * @author Lion Li
+ * @date 2021-07-26
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("test_tree")
+public class TestTree extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 涓婚敭
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 鐖禝D
+     */
+    private Long parentId;
+
+    /**
+     * 閮ㄩ棬id
+     */
+    private Long deptId;
+
+    /**
+     * 鐢ㄦ埛id
+     */
+    private Long userId;
+
+    /**
+     * 鏍戣妭鐐瑰悕
+     */
+    private String treeName;
+
+    /**
+     * 鐗堟湰
+     */
+    @Version
+    private Long version;
+
+    /**
+     * 鍒犻櫎鏍囧織
+     */
+    @TableLogic
+    private Long delFlag;
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/bo/TestDemoBo.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/bo/TestDemoBo.java
new file mode 100644
index 0000000..8134677
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/bo/TestDemoBo.java
@@ -0,0 +1,62 @@
+package org.dromara.demo.domain.bo;
+
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.demo.domain.TestDemo;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+
+/**
+ * 娴嬭瘯鍗曡〃涓氬姟瀵硅薄 test_demo
+ *
+ * @author Lion Li
+ * @date 2021-07-26
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = TestDemo.class, reverseConvertGenerate = false)
+public class TestDemoBo extends BaseEntity {
+
+    /**
+     * 涓婚敭
+     */
+    @NotNull(message = "涓婚敭涓嶈兘涓虹┖", groups = {EditGroup.class})
+    private Long id;
+
+    /**
+     * 閮ㄩ棬id
+     */
+    @NotNull(message = "閮ㄩ棬id涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
+    private Long deptId;
+
+    /**
+     * 鐢ㄦ埛id
+     */
+    @NotNull(message = "鐢ㄦ埛id涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
+    private Long userId;
+
+    /**
+     * 鎺掑簭鍙�
+     */
+    @NotNull(message = "鎺掑簭鍙蜂笉鑳戒负绌�", groups = {AddGroup.class, EditGroup.class})
+    private Integer orderNum;
+
+    /**
+     * key閿�
+     */
+    @NotBlank(message = "key閿笉鑳戒负绌�", groups = {AddGroup.class, EditGroup.class})
+    private String testKey;
+
+    /**
+     * 鍊�
+     */
+    @NotBlank(message = "鍊间笉鑳戒负绌�", groups = {AddGroup.class, EditGroup.class})
+    private String value;
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/bo/TestDemoImportVo.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/bo/TestDemoImportVo.java
new file mode 100644
index 0000000..c066118
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/bo/TestDemoImportVo.java
@@ -0,0 +1,53 @@
+package org.dromara.demo.domain.bo;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+
+/**
+ * 娴嬭瘯鍗曡〃涓氬姟瀵硅薄 test_demo
+ *
+ * @author Lion Li
+ * @date 2021-07-26
+ */
+@Data
+public class TestDemoImportVo {
+
+    /**
+     * 閮ㄩ棬id
+     */
+    @NotNull(message = "閮ㄩ棬id涓嶈兘涓虹┖")
+    @ExcelProperty(value = "閮ㄩ棬id")
+    private Long deptId;
+
+    /**
+     * 鐢ㄦ埛id
+     */
+    @NotNull(message = "鐢ㄦ埛id涓嶈兘涓虹┖")
+    @ExcelProperty(value = "鐢ㄦ埛id")
+    private Long userId;
+
+    /**
+     * 鎺掑簭鍙�
+     */
+    @NotNull(message = "鎺掑簭鍙蜂笉鑳戒负绌�")
+    @ExcelProperty(value = "鎺掑簭鍙�")
+    private Long orderNum;
+
+    /**
+     * key閿�
+     */
+    @NotBlank(message = "key閿笉鑳戒负绌�")
+    @ExcelProperty(value = "key閿�")
+    private String testKey;
+
+    /**
+     * 鍊�
+     */
+    @NotBlank(message = "鍊间笉鑳戒负绌�")
+    @ExcelProperty(value = "鍊�")
+    private String value;
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/bo/TestTreeBo.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/bo/TestTreeBo.java
new file mode 100644
index 0000000..1bbac0e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/bo/TestTreeBo.java
@@ -0,0 +1,54 @@
+package org.dromara.demo.domain.bo;
+
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.demo.domain.TestTree;
+import io.github.linpeilie.annotations.AutoMapper;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 娴嬭瘯鏍戣〃涓氬姟瀵硅薄 test_tree
+ *
+ * @author Lion Li
+ * @date 2021-07-26
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = TestTree.class, reverseConvertGenerate = false)
+public class TestTreeBo extends BaseEntity {
+
+    /**
+     * 涓婚敭
+     */
+    @NotNull(message = "涓婚敭涓嶈兘涓虹┖", groups = {EditGroup.class})
+    private Long id;
+
+    /**
+     * 鐖禝D
+     */
+    private Long parentId;
+
+    /**
+     * 閮ㄩ棬id
+     */
+    @NotNull(message = "閮ㄩ棬id涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
+    private Long deptId;
+
+    /**
+     * 鐢ㄦ埛id
+     */
+    @NotNull(message = "鐢ㄦ埛id涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
+    private Long userId;
+
+    /**
+     * 鏍戣妭鐐瑰悕
+     */
+    @NotBlank(message = "鏍戣妭鐐瑰悕涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
+    private String treeName;
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/package-info.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/package-info.java
new file mode 100644
index 0000000..cb7d83f
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/package-info.java
@@ -0,0 +1 @@
+package org.dromara.demo.domain;
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/vo/TestDemoVo.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/vo/TestDemoVo.java
new file mode 100644
index 0000000..016c2f7
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/vo/TestDemoVo.java
@@ -0,0 +1,104 @@
+package org.dromara.demo.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.common.translation.constant.TransConstant;
+import org.dromara.demo.domain.TestDemo;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 娴嬭瘯鍗曡〃瑙嗗浘瀵硅薄 test_demo
+ *
+ * @author Lion Li
+ * @date 2021-07-26
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = TestDemo.class)
+public class TestDemoVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 涓婚敭
+     */
+    @ExcelProperty(value = "涓婚敭")
+    private Long id;
+
+    /**
+     * 閮ㄩ棬id
+     */
+    @ExcelProperty(value = "閮ㄩ棬id")
+    private Long deptId;
+
+    /**
+     * 鐢ㄦ埛id
+     */
+    @ExcelProperty(value = "鐢ㄦ埛id")
+    private Long userId;
+
+    /**
+     * 鎺掑簭鍙�
+     */
+    @ExcelProperty(value = "鎺掑簭鍙�")
+    private Integer orderNum;
+
+    /**
+     * key閿�
+     */
+    @ExcelProperty(value = "key閿�")
+    private String testKey;
+
+    /**
+     * 鍊�
+     */
+    @ExcelProperty(value = "鍊�")
+    private String value;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @ExcelProperty(value = "鍒涘缓鏃堕棿")
+    private Date createTime;
+
+    /**
+     * 鍒涘缓浜�
+     */
+    @ExcelProperty(value = "鍒涘缓浜�")
+    private Long createBy;
+
+    /**
+     * 鍒涘缓浜鸿处鍙�
+     */
+    @Translation(type = TransConstant.USER_ID_TO_NAME, mapper = "createBy")
+    @ExcelProperty(value = "鍒涘缓浜鸿处鍙�")
+    private String createByName;
+
+    /**
+     * 鏇存柊鏃堕棿
+     */
+    @ExcelProperty(value = "鏇存柊鏃堕棿")
+    private Date updateTime;
+
+    /**
+     * 鏇存柊浜�
+     */
+    @ExcelProperty(value = "鏇存柊浜�")
+    private Long updateBy;
+
+    /**
+     * 鏇存柊浜鸿处鍙�
+     */
+    @Translation(type = TransConstant.USER_ID_TO_NAME, mapper = "updateBy")
+    @ExcelProperty(value = "鏇存柊浜鸿处鍙�")
+    private String updateByName;
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/vo/TestTreeVo.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/vo/TestTreeVo.java
new file mode 100644
index 0000000..58b4bdb
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/vo/TestTreeVo.java
@@ -0,0 +1,64 @@
+package org.dromara.demo.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import org.dromara.demo.domain.TestTree;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 娴嬭瘯鏍戣〃瑙嗗浘瀵硅薄 test_tree
+ *
+ * @author Lion Li
+ * @date 2021-07-26
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = TestTree.class)
+public class TestTreeVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 涓婚敭
+     */
+    private Long id;
+
+    /**
+     * 鐖秈d
+     */
+    @ExcelProperty(value = "鐖秈d")
+    private Long parentId;
+
+    /**
+     * 閮ㄩ棬id
+     */
+    @ExcelProperty(value = "閮ㄩ棬id")
+    private Long deptId;
+
+    /**
+     * 鐢ㄦ埛id
+     */
+    @ExcelProperty(value = "鐢ㄦ埛id")
+    private Long userId;
+
+    /**
+     * 鏍戣妭鐐瑰悕
+     */
+    @ExcelProperty(value = "鏍戣妭鐐瑰悕")
+    private String treeName;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @ExcelProperty(value = "鍒涘缓鏃堕棿")
+    private Date createTime;
+
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/mapper/TestDemoEncryptMapper.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/mapper/TestDemoEncryptMapper.java
new file mode 100644
index 0000000..601f97a
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/mapper/TestDemoEncryptMapper.java
@@ -0,0 +1,13 @@
+package org.dromara.demo.mapper;
+
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.demo.domain.TestDemoEncrypt;
+
+/**
+ * 娴嬭瘯鍔犲瘑鍔熻兘
+ *
+ * @author Lion Li
+ */
+public interface TestDemoEncryptMapper extends BaseMapperPlus<TestDemoEncrypt, TestDemoEncrypt> {
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/mapper/TestDemoMapper.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/mapper/TestDemoMapper.java
new file mode 100644
index 0000000..044d2b6
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/mapper/TestDemoMapper.java
@@ -0,0 +1,58 @@
+package org.dromara.demo.mapper;
+
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.dromara.common.mybatis.annotation.DataColumn;
+import org.dromara.common.mybatis.annotation.DataPermission;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.demo.domain.TestDemo;
+import org.dromara.demo.domain.vo.TestDemoVo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 娴嬭瘯鍗曡〃Mapper鎺ュ彛
+ *
+ * @author Lion Li
+ * @date 2021-07-26
+ */
+public interface TestDemoMapper extends BaseMapperPlus<TestDemo, TestDemoVo> {
+
+    @DataPermission({
+        @DataColumn(key = "deptName", value = "dept_id"),
+        @DataColumn(key = "userName", value = "user_id")
+    })
+    Page<TestDemoVo> customPageList(@Param("page") Page<TestDemo> page, @Param("ew") Wrapper<TestDemo> wrapper);
+
+    @Override
+    @DataPermission({
+        @DataColumn(key = "deptName", value = "dept_id"),
+        @DataColumn(key = "userName", value = "user_id")
+    })
+    <P extends IPage<TestDemo>> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper<TestDemo> queryWrapper);
+
+    @Override
+    @DataPermission({
+        @DataColumn(key = "deptName", value = "dept_id"),
+        @DataColumn(key = "userName", value = "user_id")
+    })
+    List<TestDemo> selectList(@Param(Constants.WRAPPER) Wrapper<TestDemo> queryWrapper);
+
+    @Override
+    @DataPermission({
+        @DataColumn(key = "deptName", value = "dept_id"),
+        @DataColumn(key = "userName", value = "user_id")
+    })
+    int updateById(@Param(Constants.ENTITY) TestDemo entity);
+
+    @Override
+    @DataPermission({
+        @DataColumn(key = "deptName", value = "dept_id"),
+        @DataColumn(key = "userName", value = "user_id")
+    })
+    int deleteBatchIds(@Param(Constants.COLL) Collection<?> idList);
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/mapper/TestTreeMapper.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/mapper/TestTreeMapper.java
new file mode 100644
index 0000000..e5f4c44
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/mapper/TestTreeMapper.java
@@ -0,0 +1,21 @@
+package org.dromara.demo.mapper;
+
+import org.dromara.common.mybatis.annotation.DataColumn;
+import org.dromara.common.mybatis.annotation.DataPermission;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.demo.domain.TestTree;
+import org.dromara.demo.domain.vo.TestTreeVo;
+
+/**
+ * 娴嬭瘯鏍戣〃Mapper鎺ュ彛
+ *
+ * @author Lion Li
+ * @date 2021-07-26
+ */
+@DataPermission({
+    @DataColumn(key = "deptName", value = "dept_id"),
+    @DataColumn(key = "userName", value = "user_id")
+})
+public interface TestTreeMapper extends BaseMapperPlus<TestTree, TestTreeVo> {
+
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/mapper/package-info.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/mapper/package-info.java
new file mode 100644
index 0000000..ff1c4df
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/mapper/package-info.java
@@ -0,0 +1 @@
+package org.dromara.demo.mapper;
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/ITestDemoService.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/ITestDemoService.java
new file mode 100644
index 0000000..bca4192
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/ITestDemoService.java
@@ -0,0 +1,71 @@
+package org.dromara.demo.service;
+
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.demo.domain.TestDemo;
+import org.dromara.demo.domain.bo.TestDemoBo;
+import org.dromara.demo.domain.vo.TestDemoVo;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 娴嬭瘯鍗曡〃Service鎺ュ彛
+ *
+ * @author Lion Li
+ * @date 2021-07-26
+ */
+public interface ITestDemoService {
+
+    /**
+     * 鏌ヨ鍗曚釜
+     *
+     * @return
+     */
+    TestDemoVo queryById(Long id);
+
+    /**
+     * 鏌ヨ鍒楄〃
+     */
+    TableDataInfo<TestDemoVo> queryPageList(TestDemoBo bo, PageQuery pageQuery);
+
+    /**
+     * 鑷畾涔夊垎椤垫煡璇�
+     */
+    TableDataInfo<TestDemoVo> customPageList(TestDemoBo bo, PageQuery pageQuery);
+
+    /**
+     * 鏌ヨ鍒楄〃
+     */
+    List<TestDemoVo> queryList(TestDemoBo bo);
+
+    /**
+     * 鏍规嵁鏂板涓氬姟瀵硅薄鎻掑叆娴嬭瘯鍗曡〃
+     *
+     * @param bo 娴嬭瘯鍗曡〃鏂板涓氬姟瀵硅薄
+     * @return
+     */
+    Boolean insertByBo(TestDemoBo bo);
+
+    /**
+     * 鏍规嵁缂栬緫涓氬姟瀵硅薄淇敼娴嬭瘯鍗曡〃
+     *
+     * @param bo 娴嬭瘯鍗曡〃缂栬緫涓氬姟瀵硅薄
+     * @return
+     */
+    Boolean updateByBo(TestDemoBo bo);
+
+    /**
+     * 鏍¢獙骞跺垹闄ゆ暟鎹�
+     *
+     * @param ids     涓婚敭闆嗗悎
+     * @param isValid 鏄惁鏍¢獙,true-鍒犻櫎鍓嶆牎楠�,false-涓嶆牎楠�
+     * @return
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     * 鎵归噺淇濆瓨
+     */
+    Boolean saveBatch(List<TestDemo> list);
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/ITestTreeService.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/ITestTreeService.java
new file mode 100644
index 0000000..9155201
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/ITestTreeService.java
@@ -0,0 +1,52 @@
+package org.dromara.demo.service;
+
+import org.dromara.demo.domain.bo.TestTreeBo;
+import org.dromara.demo.domain.vo.TestTreeVo;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 娴嬭瘯鏍戣〃Service鎺ュ彛
+ *
+ * @author Lion Li
+ * @date 2021-07-26
+ */
+public interface ITestTreeService {
+    /**
+     * 鏌ヨ鍗曚釜
+     *
+     * @return
+     */
+    TestTreeVo queryById(Long id);
+
+    /**
+     * 鏌ヨ鍒楄〃
+     */
+    List<TestTreeVo> queryList(TestTreeBo bo);
+
+    /**
+     * 鏍规嵁鏂板涓氬姟瀵硅薄鎻掑叆娴嬭瘯鏍戣〃
+     *
+     * @param bo 娴嬭瘯鏍戣〃鏂板涓氬姟瀵硅薄
+     * @return
+     */
+    Boolean insertByBo(TestTreeBo bo);
+
+    /**
+     * 鏍规嵁缂栬緫涓氬姟瀵硅薄淇敼娴嬭瘯鏍戣〃
+     *
+     * @param bo 娴嬭瘯鏍戣〃缂栬緫涓氬姟瀵硅薄
+     * @return
+     */
+    Boolean updateByBo(TestTreeBo bo);
+
+    /**
+     * 鏍¢獙骞跺垹闄ゆ暟鎹�
+     *
+     * @param ids     涓婚敭闆嗗悎
+     * @param isValid 鏄惁鏍¢獙,true-鍒犻櫎鍓嶆牎楠�,false-涓嶆牎楠�
+     * @return
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/impl/TestDemoServiceImpl.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/impl/TestDemoServiceImpl.java
new file mode 100644
index 0000000..cca48c6
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/impl/TestDemoServiceImpl.java
@@ -0,0 +1,110 @@
+package org.dromara.demo.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.demo.domain.TestDemo;
+import org.dromara.demo.domain.bo.TestDemoBo;
+import org.dromara.demo.domain.vo.TestDemoVo;
+import org.dromara.demo.mapper.TestDemoMapper;
+import org.dromara.demo.service.ITestDemoService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 娴嬭瘯鍗曡〃Service涓氬姟灞傚鐞�
+ *
+ * @author Lion Li
+ * @date 2021-07-26
+ */
+@RequiredArgsConstructor
+@Service
+public class TestDemoServiceImpl implements ITestDemoService {
+
+    private final TestDemoMapper baseMapper;
+
+    @Override
+    public TestDemoVo queryById(Long id) {
+        return baseMapper.selectVoById(id);
+    }
+
+    @Override
+    public TableDataInfo<TestDemoVo> queryPageList(TestDemoBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<TestDemo> lqw = buildQueryWrapper(bo);
+        Page<TestDemoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 鑷畾涔夊垎椤垫煡璇�
+     */
+    @Override
+    public TableDataInfo<TestDemoVo> customPageList(TestDemoBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<TestDemo> lqw = buildQueryWrapper(bo);
+        Page<TestDemoVo> result = baseMapper.customPageList(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    @Override
+    public List<TestDemoVo> queryList(TestDemoBo bo) {
+        return baseMapper.selectVoList(buildQueryWrapper(bo));
+    }
+
+    private LambdaQueryWrapper<TestDemo> buildQueryWrapper(TestDemoBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<TestDemo> lqw = Wrappers.lambdaQuery();
+        lqw.like(StringUtils.isNotBlank(bo.getTestKey()), TestDemo::getTestKey, bo.getTestKey());
+        lqw.eq(StringUtils.isNotBlank(bo.getValue()), TestDemo::getValue, bo.getValue());
+        lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
+            TestDemo::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime"));
+        return lqw;
+    }
+
+    @Override
+    public Boolean insertByBo(TestDemoBo bo) {
+        TestDemo add = MapstructUtils.convert(bo, TestDemo.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    @Override
+    public Boolean updateByBo(TestDemoBo bo) {
+        TestDemo update = MapstructUtils.convert(bo, TestDemo.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 淇濆瓨鍓嶇殑鏁版嵁鏍¢獙
+     *
+     * @param entity 瀹炰綋绫绘暟鎹�
+     */
+    private void validEntityBeforeSave(TestDemo entity) {
+        //TODO 鍋氫竴浜涙暟鎹牎楠�,濡傚敮涓�绾︽潫
+    }
+
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 鍋氫竴浜涗笟鍔′笂鐨勬牎楠�,鍒ゆ柇鏄惁闇�瑕佹牎楠�
+        }
+        return baseMapper.deleteBatchIds(ids) > 0;
+    }
+
+    @Override
+    public Boolean saveBatch(List<TestDemo> list) {
+        return baseMapper.insertBatch(list);
+    }
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/impl/TestTreeServiceImpl.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/impl/TestTreeServiceImpl.java
new file mode 100644
index 0000000..78ac135
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/impl/TestTreeServiceImpl.java
@@ -0,0 +1,87 @@
+package org.dromara.demo.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.demo.domain.TestTree;
+import org.dromara.demo.domain.bo.TestTreeBo;
+import org.dromara.demo.domain.vo.TestTreeVo;
+import org.dromara.demo.mapper.TestTreeMapper;
+import org.dromara.demo.service.ITestTreeService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 娴嬭瘯鏍戣〃Service涓氬姟灞傚鐞�
+ *
+ * @author Lion Li
+ * @date 2021-07-26
+ */
+// @DS("slave") // 鍒囨崲浠庡簱鏌ヨ
+@RequiredArgsConstructor
+@Service
+public class TestTreeServiceImpl implements ITestTreeService {
+
+    private final TestTreeMapper baseMapper;
+
+    @Override
+    public TestTreeVo queryById(Long id) {
+        return baseMapper.selectVoById(id);
+    }
+
+    // @DS("slave") // 鍒囨崲浠庡簱鏌ヨ
+    @Override
+    public List<TestTreeVo> queryList(TestTreeBo bo) {
+        LambdaQueryWrapper<TestTree> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<TestTree> buildQueryWrapper(TestTreeBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<TestTree> lqw = Wrappers.lambdaQuery();
+        lqw.like(StringUtils.isNotBlank(bo.getTreeName()), TestTree::getTreeName, bo.getTreeName());
+        lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
+            TestTree::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime"));
+        return lqw;
+    }
+
+    @Override
+    public Boolean insertByBo(TestTreeBo bo) {
+        TestTree add = MapstructUtils.convert(bo, TestTree.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    @Override
+    public Boolean updateByBo(TestTreeBo bo) {
+        TestTree update = MapstructUtils.convert(bo, TestTree.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 淇濆瓨鍓嶇殑鏁版嵁鏍¢獙
+     *
+     * @param entity 瀹炰綋绫绘暟鎹�
+     */
+    private void validEntityBeforeSave(TestTree entity) {
+        //TODO 鍋氫竴浜涙暟鎹牎楠�,濡傚敮涓�绾︽潫
+    }
+
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 鍋氫竴浜涗笟鍔′笂鐨勬牎楠�,鍒ゆ柇鏄惁闇�瑕佹牎楠�
+        }
+        return baseMapper.deleteBatchIds(ids) > 0;
+    }
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/impl/package-info.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/impl/package-info.java
new file mode 100644
index 0000000..7011984
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/impl/package-info.java
@@ -0,0 +1 @@
+package org.dromara.demo.service.impl;
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/package-info.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/package-info.java
new file mode 100644
index 0000000..16727ff
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/package-info.java
@@ -0,0 +1 @@
+package org.dromara.demo.service;
diff --git a/ruoyi-modules/ruoyi-demo/src/main/resources/mapper/demo/TestDemoMapper.xml b/ruoyi-modules/ruoyi-demo/src/main/resources/mapper/demo/TestDemoMapper.xml
index 26f86bd..dbf89a3 100644
--- a/ruoyi-modules/ruoyi-demo/src/main/resources/mapper/demo/TestDemoMapper.xml
+++ b/ruoyi-modules/ruoyi-demo/src/main/resources/mapper/demo/TestDemoMapper.xml
@@ -2,9 +2,9 @@
 <!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.demo.mapper.TestDemoMapper">
+<mapper namespace="org.dromara.demo.mapper.TestDemoMapper">
 
-    <select id="customPageList" resultType="com.ruoyi.demo.domain.vo.TestDemoVo">
+    <select id="customPageList" resultType="org.dromara.demo.domain.vo.TestDemoVo">
         SELECT * FROM test_demo ${ew.customSqlSegment}
     </select>
 
diff --git a/ruoyi-modules/ruoyi-demo/src/main/resources/mapper/demo/TestTreeMapper.xml b/ruoyi-modules/ruoyi-demo/src/main/resources/mapper/demo/TestTreeMapper.xml
index 77b4d93..d7975ec 100644
--- a/ruoyi-modules/ruoyi-demo/src/main/resources/mapper/demo/TestTreeMapper.xml
+++ b/ruoyi-modules/ruoyi-demo/src/main/resources/mapper/demo/TestTreeMapper.xml
@@ -2,6 +2,6 @@
 <!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.demo.mapper.TestTreeMapper">
+<mapper namespace="org.dromara.demo.mapper.TestTreeMapper">
 
 </mapper>
diff --git a/ruoyi-modules/ruoyi-generator/pom.xml b/ruoyi-modules/ruoyi-generator/pom.xml
index fc6db0a..d6e9dbc 100644
--- a/ruoyi-modules/ruoyi-generator/pom.xml
+++ b/ruoyi-modules/ruoyi-generator/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-modules</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -19,27 +19,27 @@
     <dependencies>
         <!-- 閫氱敤宸ュ叿-->
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-core</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-doc</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-mybatis</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-web</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-log</artifactId>
         </dependency>
 
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/config/GenConfig.java b/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/config/GenConfig.java
deleted file mode 100644
index 187426f..0000000
--- a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/config/GenConfig.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.ruoyi.generator.config;
-
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.context.annotation.PropertySource;
-import org.springframework.stereotype.Component;
-
-/**
- * 璇诲彇浠g爜鐢熸垚鐩稿叧閰嶇疆
- *
- * @author ruoyi
- */
-@Component
-@ConfigurationProperties(prefix = "gen")
-@PropertySource(value = {"classpath:generator.yml"}, encoding = "UTF-8")
-public class GenConfig {
-
-    /**
-     * 浣滆��
-     */
-    public static String author;
-
-    /**
-     * 鐢熸垚鍖呰矾寰�
-     */
-    public static String packageName;
-
-    /**
-     * 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸false
-     */
-    public static boolean autoRemovePre;
-
-    /**
-     * 琛ㄥ墠缂�(绫诲悕涓嶄細鍖呭惈琛ㄥ墠缂�)
-     */
-    public static String tablePrefix;
-
-    public static String getAuthor() {
-        return author;
-    }
-
-    @Value("${author}")
-    public void setAuthor(String author) {
-        GenConfig.author = author;
-    }
-
-    public static String getPackageName() {
-        return packageName;
-    }
-
-    @Value("${packageName}")
-    public void setPackageName(String packageName) {
-        GenConfig.packageName = packageName;
-    }
-
-    public static boolean getAutoRemovePre() {
-        return autoRemovePre;
-    }
-
-    @Value("${autoRemovePre}")
-    public void setAutoRemovePre(boolean autoRemovePre) {
-        GenConfig.autoRemovePre = autoRemovePre;
-    }
-
-    public static String getTablePrefix() {
-        return tablePrefix;
-    }
-
-    @Value("${tablePrefix}")
-    public void setTablePrefix(String tablePrefix) {
-        GenConfig.tablePrefix = tablePrefix;
-    }
-}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/constant/GenConstants.java b/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/constant/GenConstants.java
deleted file mode 100644
index eb0d12f..0000000
--- a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/constant/GenConstants.java
+++ /dev/null
@@ -1,186 +0,0 @@
-package com.ruoyi.generator.constant;
-
-/**
- * 浠g爜鐢熸垚閫氱敤甯搁噺
- *
- * @author ruoyi
- */
-public interface GenConstants {
-    /**
-     * 鍗曡〃锛堝鍒犳敼鏌ワ級
-     */
-    String TPL_CRUD = "crud";
-
-    /**
-     * 鏍戣〃锛堝鍒犳敼鏌ワ級
-     */
-    String TPL_TREE = "tree";
-
-    /**
-     * 鏍戠紪鐮佸瓧娈�
-     */
-    String TREE_CODE = "treeCode";
-
-    /**
-     * 鏍戠埗缂栫爜瀛楁
-     */
-    String TREE_PARENT_CODE = "treeParentCode";
-
-    /**
-     * 鏍戝悕绉板瓧娈�
-     */
-    String TREE_NAME = "treeName";
-
-    /**
-     * 涓婄骇鑿滃崟ID瀛楁
-     */
-    String PARENT_MENU_ID = "parentMenuId";
-
-    /**
-     * 涓婄骇鑿滃崟鍚嶇О瀛楁
-     */
-    String PARENT_MENU_NAME = "parentMenuName";
-
-    /**
-     * 鏁版嵁搴撳瓧绗︿覆绫诲瀷
-     */
-    String[] COLUMNTYPE_STR = {"char", "varchar", "enum", "set", "nchar", "nvarchar", "varchar2", "nvarchar2"};
-
-    /**
-     * 鏁版嵁搴撴枃鏈被鍨�
-     */
-    String[] COLUMNTYPE_TEXT = {"tinytext", "text", "mediumtext", "longtext", "binary", "varbinary", "blob",
-        "ntext", "image", "bytea"};
-
-    /**
-     * 鏁版嵁搴撴椂闂寸被鍨�
-     */
-    String[] COLUMNTYPE_TIME = {"datetime", "time", "date", "timestamp", "year", "interval",
-        "smalldatetime", "datetime2", "datetimeoffset"};
-
-    /**
-     * 鏁版嵁搴撴暟瀛楃被鍨�
-     */
-    String[] COLUMNTYPE_NUMBER = {"tinyint", "smallint", "mediumint", "int", "number", "integer",
-        "bit", "bigint", "float", "double", "decimal", "numeric", "real", "double precision",
-        "smallserial", "serial", "bigserial", "money", "smallmoney"};
-
-    /**
-     * BO瀵硅薄 涓嶉渶瑕佹坊鍔犲瓧娈�
-     */
-    String[] COLUMNNAME_NOT_ADD = {"create_dept", "create_by", "create_time", "del_flag", "update_by",
-        "update_time", "version", "tenant_id"};
-
-    /**
-     * BO瀵硅薄 涓嶉渶瑕佺紪杈戝瓧娈�
-     */
-    String[] COLUMNNAME_NOT_EDIT = {"create_dept", "create_by", "create_time", "del_flag", "update_by",
-        "update_time", "version", "tenant_id"};
-
-    /**
-     * VO瀵硅薄 涓嶉渶瑕佽繑鍥炲瓧娈�
-     */
-    String[] COLUMNNAME_NOT_LIST = {"create_dept", "create_by", "create_time", "del_flag", "update_by",
-        "update_time", "version", "tenant_id"};
-
-    /**
-     * BO瀵硅薄 涓嶉渶瑕佹煡璇㈠瓧娈�
-     */
-    String[] COLUMNNAME_NOT_QUERY = {"id", "create_dept", "create_by", "create_time", "del_flag", "update_by",
-        "update_time", "remark", "version", "tenant_id"};
-
-    /**
-     * Entity鍩虹被瀛楁
-     */
-    String[] BASE_ENTITY = {"createDept", "createBy", "createTime", "updateBy", "updateTime", "tenantId"};
-
-    /**
-     * 鏂囨湰妗�
-     */
-    String HTML_INPUT = "input";
-
-    /**
-     * 鏂囨湰鍩�
-     */
-    String HTML_TEXTAREA = "textarea";
-
-    /**
-     * 涓嬫媺妗�
-     */
-    String HTML_SELECT = "select";
-
-    /**
-     * 鍗曢�夋
-     */
-    String HTML_RADIO = "radio";
-
-    /**
-     * 澶嶉�夋
-     */
-    String HTML_CHECKBOX = "checkbox";
-
-    /**
-     * 鏃ユ湡鎺т欢
-     */
-    String HTML_DATETIME = "datetime";
-
-    /**
-     * 鍥剧墖涓婁紶鎺т欢
-     */
-    String HTML_IMAGE_UPLOAD = "imageUpload";
-
-    /**
-     * 鏂囦欢涓婁紶鎺т欢
-     */
-    String HTML_FILE_UPLOAD = "fileUpload";
-
-    /**
-     * 瀵屾枃鏈帶浠�
-     */
-    String HTML_EDITOR = "editor";
-
-    /**
-     * 瀛楃涓茬被鍨�
-     */
-    String TYPE_STRING = "String";
-
-    /**
-     * 鏁村瀷
-     */
-    String TYPE_INTEGER = "Integer";
-
-    /**
-     * 闀挎暣鍨�
-     */
-    String TYPE_LONG = "Long";
-
-    /**
-     * 娴偣鍨�
-     */
-    String TYPE_DOUBLE = "Double";
-
-    /**
-     * 楂樼簿搴﹁绠楃被鍨�
-     */
-    String TYPE_BIGDECIMAL = "BigDecimal";
-
-    /**
-     * 鏃堕棿绫诲瀷
-     */
-    String TYPE_DATE = "Date";
-
-    /**
-     * 妯$硦鏌ヨ
-     */
-    String QUERY_LIKE = "LIKE";
-
-    /**
-     * 鐩哥瓑鏌ヨ
-     */
-    String QUERY_EQ = "EQ";
-
-    /**
-     * 闇�瑕�
-     */
-    String REQUIRE = "1";
-}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java b/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java
deleted file mode 100644
index 6dd4b78..0000000
--- a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java
+++ /dev/null
@@ -1,207 +0,0 @@
-package com.ruoyi.generator.controller;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import cn.hutool.core.convert.Convert;
-import cn.hutool.core.io.IoUtil;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.log.annotation.Log;
-import com.ruoyi.common.log.enums.BusinessType;
-import com.ruoyi.generator.domain.GenTable;
-import com.ruoyi.generator.domain.GenTableColumn;
-import com.ruoyi.generator.service.IGenTableService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import jakarta.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 浠g爜鐢熸垚 鎿嶄綔澶勭悊
- *
- * @author Lion Li
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/tool/gen")
-public class GenController extends BaseController {
-
-    private final IGenTableService genTableService;
-
-    /**
-     * 鏌ヨ浠g爜鐢熸垚鍒楄〃
-     */
-    @SaCheckPermission("tool:gen:list")
-    @GetMapping("/list")
-    public TableDataInfo<GenTable> genList(GenTable genTable, PageQuery pageQuery) {
-        return genTableService.selectPageGenTableList(genTable, pageQuery);
-    }
-
-    /**
-     * 淇敼浠g爜鐢熸垚涓氬姟
-     *
-     * @param tableId 琛↖D
-     */
-    @SaCheckPermission("tool:gen:query")
-    @GetMapping(value = "/{tableId}")
-    public R<Map<String, Object>> getInfo(@PathVariable Long tableId) {
-        GenTable table = genTableService.selectGenTableById(tableId);
-        List<GenTable> tables = genTableService.selectGenTableAll();
-        List<GenTableColumn> list = genTableService.selectGenTableColumnListByTableId(tableId);
-        Map<String, Object> map = new HashMap<String, Object>();
-        map.put("info", table);
-        map.put("rows", list);
-        map.put("tables", tables);
-        return R.ok(map);
-    }
-
-    /**
-     * 鏌ヨ鏁版嵁搴撳垪琛�
-     */
-    @SaCheckPermission("tool:gen:list")
-    @GetMapping("/db/list")
-    public TableDataInfo<GenTable> dataList(GenTable genTable, PageQuery pageQuery) {
-        return genTableService.selectPageDbTableList(genTable, pageQuery);
-    }
-
-    /**
-     * 鏌ヨ鏁版嵁琛ㄥ瓧娈靛垪琛�
-     *
-     * @param tableId 琛↖D
-     */
-    @SaCheckPermission("tool:gen:list")
-    @GetMapping(value = "/column/{tableId}")
-    public TableDataInfo<GenTableColumn> columnList(Long tableId) {
-        TableDataInfo<GenTableColumn> dataInfo = new TableDataInfo<>();
-        List<GenTableColumn> list = genTableService.selectGenTableColumnListByTableId(tableId);
-        dataInfo.setRows(list);
-        dataInfo.setTotal(list.size());
-        return dataInfo;
-    }
-
-    /**
-     * 瀵煎叆琛ㄧ粨鏋勶紙淇濆瓨锛�
-     *
-     * @param tables 琛ㄥ悕涓�
-     */
-    @SaCheckPermission("tool:gen:import")
-    @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.IMPORT)
-    @PostMapping("/importTable")
-    public R<Void> importTableSave(String tables) {
-        String[] tableNames = Convert.toStrArray(tables);
-        // 鏌ヨ琛ㄤ俊鎭�
-        List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames);
-        genTableService.importGenTable(tableList);
-        return R.ok();
-    }
-
-    /**
-     * 淇敼淇濆瓨浠g爜鐢熸垚涓氬姟
-     */
-    @SaCheckPermission("tool:gen:edit")
-    @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.UPDATE)
-    @PutMapping
-    public R<Void> editSave(@Validated @RequestBody GenTable genTable) {
-        genTableService.validateEdit(genTable);
-        genTableService.updateGenTable(genTable);
-        return R.ok();
-    }
-
-    /**
-     * 鍒犻櫎浠g爜鐢熸垚
-     *
-     * @param tableIds 琛↖D涓�
-     */
-    @SaCheckPermission("tool:gen:remove")
-    @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{tableIds}")
-    public R<Void> remove(@PathVariable Long[] tableIds) {
-        genTableService.deleteGenTableByIds(tableIds);
-        return R.ok();
-    }
-
-    /**
-     * 棰勮浠g爜
-     *
-     * @param tableId 琛↖D
-     */
-    @SaCheckPermission("tool:gen:preview")
-    @GetMapping("/preview/{tableId}")
-    public R<Map<String, String>> preview(@PathVariable("tableId") Long tableId) throws IOException {
-        Map<String, String> dataMap = genTableService.previewCode(tableId);
-        return R.ok(dataMap);
-    }
-
-    /**
-     * 鐢熸垚浠g爜锛堜笅杞芥柟寮忥級
-     *
-     * @param tableName 琛ㄥ悕
-     */
-    @SaCheckPermission("tool:gen:code")
-    @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.GENCODE)
-    @GetMapping("/download/{tableName}")
-    public void download(HttpServletResponse response, @PathVariable("tableName") String tableName) throws IOException {
-        byte[] data = genTableService.downloadCode(tableName);
-        genCode(response, data);
-    }
-
-    /**
-     * 鐢熸垚浠g爜锛堣嚜瀹氫箟璺緞锛�
-     *
-     * @param tableName 琛ㄥ悕
-     */
-    @SaCheckPermission("tool:gen:code")
-    @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.GENCODE)
-    @GetMapping("/genCode/{tableName}")
-    public R<Void> genCode(@PathVariable("tableName") String tableName) {
-        genTableService.generatorCode(tableName);
-        return R.ok();
-    }
-
-    /**
-     * 鍚屾鏁版嵁搴�
-     *
-     * @param tableName 琛ㄥ悕
-     */
-    @SaCheckPermission("tool:gen:edit")
-    @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.UPDATE)
-    @GetMapping("/synchDb/{tableName}")
-    public R<Void> synchDb(@PathVariable("tableName") String tableName) {
-        genTableService.synchDb(tableName);
-        return R.ok();
-    }
-
-    /**
-     * 鎵归噺鐢熸垚浠g爜
-     *
-     * @param tables 琛ㄥ悕涓�
-     */
-    @SaCheckPermission("tool:gen:code")
-    @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.GENCODE)
-    @GetMapping("/batchGenCode")
-    public void batchGenCode(HttpServletResponse response, String tables) throws IOException {
-        String[] tableNames = Convert.toStrArray(tables);
-        byte[] data = genTableService.downloadCode(tableNames);
-        genCode(response, data);
-    }
-
-    /**
-     * 鐢熸垚zip鏂囦欢
-     */
-    private void genCode(HttpServletResponse response, byte[] data) throws IOException {
-        response.reset();
-        response.addHeader("Access-Control-Allow-Origin", "*");
-        response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
-        response.setHeader("Content-Disposition", "attachment; filename=\"ruoyi.zip\"");
-        response.addHeader("Content-Length", "" + data.length);
-        response.setContentType("application/octet-stream; charset=UTF-8");
-        IoUtil.write(response.getOutputStream(), false, data);
-    }
-}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTable.java b/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTable.java
deleted file mode 100644
index ed1ea1a..0000000
--- a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTable.java
+++ /dev/null
@@ -1,190 +0,0 @@
-package com.ruoyi.generator.domain;
-
-import com.baomidou.mybatisplus.annotation.FieldStrategy;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-import com.ruoyi.generator.constant.GenConstants;
-import jakarta.validation.Valid;
-import jakarta.validation.constraints.NotBlank;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import java.util.List;
-
-/**
- * 涓氬姟琛� gen_table
- *
- * @author Lion Li
- */
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("gen_table")
-public class GenTable extends BaseEntity {
-
-    /**
-     * 缂栧彿
-     */
-    @TableId(value = "table_id")
-    private Long tableId;
-
-    /**
-     * 琛ㄥ悕绉�
-     */
-    @NotBlank(message = "琛ㄥ悕绉颁笉鑳戒负绌�")
-    private String tableName;
-
-    /**
-     * 琛ㄦ弿杩�
-     */
-    @NotBlank(message = "琛ㄦ弿杩颁笉鑳戒负绌�")
-    private String tableComment;
-
-    /**
-     * 鍏宠仈鐖惰〃鐨勮〃鍚�
-     */
-    private String subTableName;
-
-    /**
-     * 鏈〃鍏宠仈鐖惰〃鐨勫閿悕
-     */
-    private String subTableFkName;
-
-    /**
-     * 瀹炰綋绫诲悕绉�(棣栧瓧姣嶅ぇ鍐�)
-     */
-    @NotBlank(message = "瀹炰綋绫诲悕绉颁笉鑳戒负绌�")
-    private String className;
-
-    /**
-     * 浣跨敤鐨勬ā鏉匡紙crud鍗曡〃鎿嶄綔 tree鏍戣〃鎿嶄綔 sub涓诲瓙琛ㄦ搷浣滐級
-     */
-    private String tplCategory;
-
-    /**
-     * 鐢熸垚鍖呰矾寰�
-     */
-    @NotBlank(message = "鐢熸垚鍖呰矾寰勪笉鑳戒负绌�")
-    private String packageName;
-
-    /**
-     * 鐢熸垚妯″潡鍚�
-     */
-    @NotBlank(message = "鐢熸垚妯″潡鍚嶄笉鑳戒负绌�")
-    private String moduleName;
-
-    /**
-     * 鐢熸垚涓氬姟鍚�
-     */
-    @NotBlank(message = "鐢熸垚涓氬姟鍚嶄笉鑳戒负绌�")
-    private String businessName;
-
-    /**
-     * 鐢熸垚鍔熻兘鍚�
-     */
-    @NotBlank(message = "鐢熸垚鍔熻兘鍚嶄笉鑳戒负绌�")
-    private String functionName;
-
-    /**
-     * 鐢熸垚浣滆��
-     */
-    @NotBlank(message = "浣滆�呬笉鑳戒负绌�")
-    private String functionAuthor;
-
-    /**
-     * 鐢熸垚浠g爜鏂瑰紡锛�0zip鍘嬬缉鍖� 1鑷畾涔夎矾寰勶級
-     */
-    private String genType;
-
-    /**
-     * 鐢熸垚璺緞锛堜笉濉粯璁ら」鐩矾寰勶級
-     */
-    @TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
-    private String genPath;
-
-    /**
-     * 涓婚敭淇℃伅
-     */
-    @TableField(exist = false)
-    private GenTableColumn pkColumn;
-
-    /**
-     * 琛ㄥ垪淇℃伅
-     */
-    @Valid
-    @TableField(exist = false)
-    private List<GenTableColumn> columns;
-
-    /**
-     * 鍏跺畠鐢熸垚閫夐」
-     */
-    private String options;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-    /**
-     * 鏍戠紪鐮佸瓧娈�
-     */
-    @TableField(exist = false)
-    private String treeCode;
-
-    /**
-     * 鏍戠埗缂栫爜瀛楁
-     */
-    @TableField(exist = false)
-    private String treeParentCode;
-
-    /**
-     * 鏍戝悕绉板瓧娈�
-     */
-    @TableField(exist = false)
-    private String treeName;
-
-    /*
-     * 鑿滃崟id鍒楄〃
-     */
-    @TableField(exist = false)
-    private List<Long> menuIds;
-
-    /**
-     * 涓婄骇鑿滃崟ID瀛楁
-     */
-    @TableField(exist = false)
-    private String parentMenuId;
-
-    /**
-     * 涓婄骇鑿滃崟鍚嶇О瀛楁
-     */
-    @TableField(exist = false)
-    private String parentMenuName;
-
-    public boolean isTree() {
-        return isTree(this.tplCategory);
-    }
-
-    public static boolean isTree(String tplCategory) {
-        return tplCategory != null && StringUtils.equals(GenConstants.TPL_TREE, tplCategory);
-    }
-
-    public boolean isCrud() {
-        return isCrud(this.tplCategory);
-    }
-
-    public static boolean isCrud(String tplCategory) {
-        return tplCategory != null && StringUtils.equals(GenConstants.TPL_CRUD, tplCategory);
-    }
-
-    public boolean isSuperColumn(String javaField) {
-        return isSuperColumn(this.tplCategory, javaField);
-    }
-
-    public static boolean isSuperColumn(String tplCategory, String javaField) {
-        return StringUtils.equalsAnyIgnoreCase(javaField, GenConstants.BASE_ENTITY);
-    }
-}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTableColumn.java b/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTableColumn.java
deleted file mode 100644
index f374bf9..0000000
--- a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTableColumn.java
+++ /dev/null
@@ -1,223 +0,0 @@
-package com.ruoyi.generator.domain;
-
-import com.baomidou.mybatisplus.annotation.FieldStrategy;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import org.apache.ibatis.type.JdbcType;
-
-import jakarta.validation.constraints.NotBlank;
-
-/**
- * 浠g爜鐢熸垚涓氬姟瀛楁琛� gen_table_column
- *
- * @author Lion Li
- */
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("gen_table_column")
-public class GenTableColumn extends BaseEntity {
-
-    /**
-     * 缂栧彿
-     */
-    @TableId(value = "column_id")
-    private Long columnId;
-
-    /**
-     * 褰掑睘琛ㄧ紪鍙�
-     */
-    private Long tableId;
-
-    /**
-     * 鍒楀悕绉�
-     */
-    private String columnName;
-
-    /**
-     * 鍒楁弿杩�
-     */
-    @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR)
-    private String columnComment;
-
-    /**
-     * 鍒楃被鍨�
-     */
-    private String columnType;
-
-    /**
-     * JAVA绫诲瀷
-     */
-    private String javaType;
-
-    /**
-     * JAVA瀛楁鍚�
-     */
-    @NotBlank(message = "Java灞炴�т笉鑳戒负绌�")
-    private String javaField;
-
-    /**
-     * 鏄惁涓婚敭锛�1鏄級
-     */
-    @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR)
-    private String isPk;
-
-    /**
-     * 鏄惁鑷锛�1鏄級
-     */
-    @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR)
-    private String isIncrement;
-
-    /**
-     * 鏄惁蹇呭~锛�1鏄級
-     */
-    @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR)
-    private String isRequired;
-
-    /**
-     * 鏄惁涓烘彃鍏ュ瓧娈碉紙1鏄級
-     */
-    @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR)
-    private String isInsert;
-
-    /**
-     * 鏄惁缂栬緫瀛楁锛�1鏄級
-     */
-    @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR)
-    private String isEdit;
-
-    /**
-     * 鏄惁鍒楄〃瀛楁锛�1鏄級
-     */
-    @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR)
-    private String isList;
-
-    /**
-     * 鏄惁鏌ヨ瀛楁锛�1鏄級
-     */
-    @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR)
-    private String isQuery;
-
-    /**
-     * 鏌ヨ鏂瑰紡锛圗Q绛変簬銆丯E涓嶇瓑浜庛�丟T澶т簬銆丩T灏忎簬銆丩IKE妯$硦銆丅ETWEEN鑼冨洿锛�
-     */
-    private String queryType;
-
-    /**
-     * 鏄剧ず绫诲瀷锛坕nput鏂囨湰妗嗐�乼extarea鏂囨湰鍩熴�乻elect涓嬫媺妗嗐�乧heckbox澶嶉�夋銆乺adio鍗曢�夋銆乨atetime鏃ユ湡鎺т欢銆乮mage鍥剧墖涓婁紶鎺т欢銆乽pload鏂囦欢涓婁紶鎺т欢銆乪ditor瀵屾枃鏈帶浠讹級
-     */
-    private String htmlType;
-
-    /**
-     * 瀛楀吀绫诲瀷
-     */
-    private String dictType;
-
-    /**
-     * 鎺掑簭
-     */
-    private Integer sort;
-
-    public String getCapJavaField() {
-        return StringUtils.capitalize(javaField);
-    }
-
-    public boolean isPk() {
-        return isPk(this.isPk);
-    }
-
-    public boolean isPk(String isPk) {
-        return isPk != null && StringUtils.equals("1", isPk);
-    }
-
-    public boolean isIncrement() {
-        return isIncrement(this.isIncrement);
-    }
-
-    public boolean isIncrement(String isIncrement) {
-        return isIncrement != null && StringUtils.equals("1", isIncrement);
-    }
-
-    public boolean isRequired() {
-        return isRequired(this.isRequired);
-    }
-
-    public boolean isRequired(String isRequired) {
-        return isRequired != null && StringUtils.equals("1", isRequired);
-    }
-
-    public boolean isInsert() {
-        return isInsert(this.isInsert);
-    }
-
-    public boolean isInsert(String isInsert) {
-        return isInsert != null && StringUtils.equals("1", isInsert);
-    }
-
-    public boolean isEdit() {
-        return isInsert(this.isEdit);
-    }
-
-    public boolean isEdit(String isEdit) {
-        return isEdit != null && StringUtils.equals("1", isEdit);
-    }
-
-    public boolean isList() {
-        return isList(this.isList);
-    }
-
-    public boolean isList(String isList) {
-        return isList != null && StringUtils.equals("1", isList);
-    }
-
-    public boolean isQuery() {
-        return isQuery(this.isQuery);
-    }
-
-    public boolean isQuery(String isQuery) {
-        return isQuery != null && StringUtils.equals("1", isQuery);
-    }
-
-    public boolean isSuperColumn() {
-        return isSuperColumn(this.javaField);
-    }
-
-    public static boolean isSuperColumn(String javaField) {
-        return StringUtils.equalsAnyIgnoreCase(javaField,
-            // BaseEntity
-            "createBy", "createTime", "updateBy", "updateTime",
-            // TreeEntity
-            "parentName", "parentId");
-    }
-
-    public boolean isUsableColumn() {
-        return isUsableColumn(javaField);
-    }
-
-    public static boolean isUsableColumn(String javaField) {
-        // isSuperColumn()涓殑鍚嶅崟鐢ㄤ簬閬垮厤鐢熸垚澶氫綑Domain灞炴�э紝鑻ユ煇浜涘睘鎬у湪鐢熸垚椤甸潰鏃堕渶瑕佺敤鍒颁笉鑳藉拷鐣ワ紝鍒欐斁鍦ㄦ澶勭櫧鍚嶅崟
-        return StringUtils.equalsAnyIgnoreCase(javaField, "parentId", "orderNum", "remark");
-    }
-
-    public String readConverterExp() {
-        String remarks = StringUtils.substringBetween(this.columnComment, "锛�", "锛�");
-        StringBuffer sb = new StringBuffer();
-        if (StringUtils.isNotEmpty(remarks)) {
-            for (String value : remarks.split(" ")) {
-                if (StringUtils.isNotEmpty(value)) {
-                    Object startStr = value.subSequence(0, 1);
-                    String endStr = value.substring(1);
-                    sb.append(StringUtils.EMPTY).append(startStr).append("=").append(endStr).append(StringUtils.SEPARATOR);
-                }
-            }
-            return sb.deleteCharAt(sb.length() - 1).toString();
-        } else {
-            return this.columnComment;
-        }
-    }
-}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableColumnMapper.java b/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableColumnMapper.java
deleted file mode 100644
index 7ed4c19..0000000
--- a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableColumnMapper.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.ruoyi.generator.mapper;
-
-import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.generator.domain.GenTableColumn;
-
-import java.util.List;
-
-/**
- * 涓氬姟瀛楁 鏁版嵁灞�
- *
- * @author Lion Li
- */
-@InterceptorIgnore(dataPermission = "true", tenantLine = "true")
-public interface GenTableColumnMapper extends BaseMapperPlus<GenTableColumn, GenTableColumn> {
-    /**
-     * 鏍规嵁琛ㄥ悕绉版煡璇㈠垪淇℃伅
-     *
-     * @param tableName 琛ㄥ悕绉�
-     * @return 鍒椾俊鎭�
-     */
-    List<GenTableColumn> selectDbTableColumnsByName(String tableName);
-
-}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableMapper.java b/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableMapper.java
deleted file mode 100644
index 43d765f..0000000
--- a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableMapper.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package com.ruoyi.generator.mapper;
-
-import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.generator.domain.GenTable;
-import org.apache.ibatis.annotations.Param;
-
-import java.util.List;
-
-/**
- * 涓氬姟 鏁版嵁灞�
- *
- * @author Lion Li
- */
-@InterceptorIgnore(dataPermission = "true", tenantLine = "true")
-public interface GenTableMapper extends BaseMapperPlus<GenTable, GenTable> {
-
-    /**
-     * 鏌ヨ鎹簱鍒楄〃
-     *
-     * @param genTable 鏌ヨ鏉′欢
-     * @return 鏁版嵁搴撹〃闆嗗悎
-     */
-    Page<GenTable> selectPageDbTableList(@Param("page") Page<GenTable> page, @Param("genTable") GenTable genTable);
-
-    /**
-     * 鏌ヨ鎹簱鍒楄〃
-     *
-     * @param tableNames 琛ㄥ悕绉扮粍
-     * @return 鏁版嵁搴撹〃闆嗗悎
-     */
-    List<GenTable> selectDbTableListByNames(String[] tableNames);
-
-    /**
-     * 鏌ヨ鎵�鏈夎〃淇℃伅
-     *
-     * @return 琛ㄤ俊鎭泦鍚�
-     */
-    List<GenTable> selectGenTableAll();
-
-    /**
-     * 鏌ヨ琛↖D涓氬姟淇℃伅
-     *
-     * @param id 涓氬姟ID
-     * @return 涓氬姟淇℃伅
-     */
-    GenTable selectGenTableById(Long id);
-
-    /**
-     * 鏌ヨ琛ㄥ悕绉颁笟鍔′俊鎭�
-     *
-     * @param tableName 琛ㄥ悕绉�
-     * @return 涓氬姟淇℃伅
-     */
-    GenTable selectGenTableByName(String tableName);
-
-}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java b/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java
deleted file mode 100644
index 3a4091c..0000000
--- a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java
+++ /dev/null
@@ -1,459 +0,0 @@
-package com.ruoyi.generator.service;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.io.IoUtil;
-import cn.hutool.core.lang.Dict;
-import cn.hutool.core.util.ObjectUtil;
-import com.baomidou.dynamic.datasource.annotation.DS;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.core.constant.Constants;
-import com.ruoyi.generator.constant.GenConstants;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.utils.StreamUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.core.utils.file.FileUtils;
-import com.ruoyi.common.json.utils.JsonUtils;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.satoken.utils.LoginHelper;
-import com.ruoyi.generator.domain.GenTable;
-import com.ruoyi.generator.domain.GenTableColumn;
-import com.ruoyi.generator.mapper.GenTableColumnMapper;
-import com.ruoyi.generator.mapper.GenTableMapper;
-import com.ruoyi.generator.util.GenUtils;
-import com.ruoyi.generator.util.VelocityInitializer;
-import com.ruoyi.generator.util.VelocityUtils;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.velocity.Template;
-import org.apache.velocity.VelocityContext;
-import org.apache.velocity.app.Velocity;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.StringWriter;
-import java.nio.charset.StandardCharsets;
-import java.util.*;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
-
-/**
- * 涓氬姟 鏈嶅姟灞傚疄鐜�
- *
- * @author Lion Li
- */
-@DS("#header.datasource")
-@Slf4j
-@RequiredArgsConstructor
-@Service
-public class GenTableServiceImpl implements IGenTableService {
-
-    private final GenTableMapper baseMapper;
-    private final GenTableColumnMapper genTableColumnMapper;
-    private final IdentifierGenerator identifierGenerator;
-
-    /**
-     * 鏌ヨ涓氬姟瀛楁鍒楄〃
-     *
-     * @param tableId 涓氬姟瀛楁缂栧彿
-     * @return 涓氬姟瀛楁闆嗗悎
-     */
-    @Override
-    public List<GenTableColumn> selectGenTableColumnListByTableId(Long tableId) {
-        return genTableColumnMapper.selectList(new LambdaQueryWrapper<GenTableColumn>()
-            .eq(GenTableColumn::getTableId, tableId)
-            .orderByAsc(GenTableColumn::getSort));
-    }
-
-    /**
-     * 鏌ヨ涓氬姟淇℃伅
-     *
-     * @param id 涓氬姟ID
-     * @return 涓氬姟淇℃伅
-     */
-    @Override
-    public GenTable selectGenTableById(Long id) {
-        GenTable genTable = baseMapper.selectGenTableById(id);
-        setTableFromOptions(genTable);
-        return genTable;
-    }
-
-    @Override
-    public TableDataInfo<GenTable> selectPageGenTableList(GenTable genTable, PageQuery pageQuery) {
-        Page<GenTable> page = baseMapper.selectPage(pageQuery.build(), this.buildGenTableQueryWrapper(genTable));
-        return TableDataInfo.build(page);
-    }
-
-    private QueryWrapper<GenTable> buildGenTableQueryWrapper(GenTable genTable) {
-        Map<String, Object> params = genTable.getParams();
-        QueryWrapper<GenTable> wrapper = Wrappers.query();
-        wrapper.like(StringUtils.isNotBlank(genTable.getTableName()), "lower(table_name)", StringUtils.lowerCase(genTable.getTableName()))
-            .like(StringUtils.isNotBlank(genTable.getTableComment()), "lower(table_comment)", StringUtils.lowerCase(genTable.getTableComment()))
-            .between(params.get("beginTime") != null && params.get("endTime") != null,
-                "create_time", params.get("beginTime"), params.get("endTime"));
-        return wrapper;
-    }
-
-
-    @Override
-    public TableDataInfo<GenTable> selectPageDbTableList(GenTable genTable, PageQuery pageQuery) {
-        Page<GenTable> page = baseMapper.selectPageDbTableList(pageQuery.build(), genTable);
-        return TableDataInfo.build(page);
-    }
-
-    /**
-     * 鏌ヨ鎹簱鍒楄〃
-     *
-     * @param tableNames 琛ㄥ悕绉扮粍
-     * @return 鏁版嵁搴撹〃闆嗗悎
-     */
-    @Override
-    public List<GenTable> selectDbTableListByNames(String[] tableNames) {
-        return baseMapper.selectDbTableListByNames(tableNames);
-    }
-
-    /**
-     * 鏌ヨ鎵�鏈夎〃淇℃伅
-     *
-     * @return 琛ㄤ俊鎭泦鍚�
-     */
-    @Override
-    public List<GenTable> selectGenTableAll() {
-        return baseMapper.selectGenTableAll();
-    }
-
-    /**
-     * 淇敼涓氬姟
-     *
-     * @param genTable 涓氬姟淇℃伅
-     * @return 缁撴灉
-     */
-    @Transactional(rollbackFor = Exception.class)
-    @Override
-    public void updateGenTable(GenTable genTable) {
-        String options = JsonUtils.toJsonString(genTable.getParams());
-        genTable.setOptions(options);
-        int row = baseMapper.updateById(genTable);
-        if (row > 0) {
-            for (GenTableColumn cenTableColumn : genTable.getColumns()) {
-                genTableColumnMapper.updateById(cenTableColumn);
-            }
-        }
-    }
-
-    /**
-     * 鍒犻櫎涓氬姟瀵硅薄
-     *
-     * @param tableIds 闇�瑕佸垹闄ょ殑鏁版嵁ID
-     * @return 缁撴灉
-     */
-    @Transactional(rollbackFor = Exception.class)
-    @Override
-    public void deleteGenTableByIds(Long[] tableIds) {
-        List<Long> ids = Arrays.asList(tableIds);
-        baseMapper.deleteBatchIds(ids);
-        genTableColumnMapper.delete(new LambdaQueryWrapper<GenTableColumn>().in(GenTableColumn::getTableId, ids));
-    }
-
-    /**
-     * 瀵煎叆琛ㄧ粨鏋�
-     *
-     * @param tableList 瀵煎叆琛ㄥ垪琛�
-     */
-    @Transactional(rollbackFor = Exception.class)
-    @Override
-    public void importGenTable(List<GenTable> tableList) {
-        String operName = LoginHelper.getUsername();
-        try {
-            for (GenTable table : tableList) {
-                String tableName = table.getTableName();
-                GenUtils.initTable(table, operName);
-                int row = baseMapper.insert(table);
-                if (row > 0) {
-                    // 淇濆瓨鍒椾俊鎭�
-                    List<GenTableColumn> genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName);
-                    List<GenTableColumn> saveColumns = new ArrayList<>();
-                    for (GenTableColumn column : genTableColumns) {
-                        GenUtils.initColumnField(column, table);
-                        saveColumns.add(column);
-                    }
-                    if (CollUtil.isNotEmpty(saveColumns)) {
-                        genTableColumnMapper.insertBatch(saveColumns);
-                    }
-                }
-            }
-        } catch (Exception e) {
-            throw new ServiceException("瀵煎叆澶辫触锛�" + e.getMessage());
-        }
-    }
-
-    /**
-     * 棰勮浠g爜
-     *
-     * @param tableId 琛ㄧ紪鍙�
-     * @return 棰勮鏁版嵁鍒楄〃
-     */
-    @Override
-    public Map<String, String> previewCode(Long tableId) {
-        Map<String, String> dataMap = new LinkedHashMap<>();
-        // 鏌ヨ琛ㄤ俊鎭�
-        GenTable table = baseMapper.selectGenTableById(tableId);
-        List<Long> menuIds = new ArrayList<>();
-        for (int i = 0; i < 6; i++) {
-            menuIds.add(identifierGenerator.nextId(null).longValue());
-        }
-        table.setMenuIds(menuIds);
-        // 璁剧疆涓婚敭鍒椾俊鎭�
-        setPkColumn(table);
-        VelocityInitializer.initVelocity();
-
-        VelocityContext context = VelocityUtils.prepareContext(table);
-
-        // 鑾峰彇妯℃澘鍒楄〃
-        List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
-        for (String template : templates) {
-            // 娓叉煋妯℃澘
-            StringWriter sw = new StringWriter();
-            Template tpl = Velocity.getTemplate(template, Constants.UTF8);
-            tpl.merge(context, sw);
-            dataMap.put(template, sw.toString());
-        }
-        return dataMap;
-    }
-
-    /**
-     * 鐢熸垚浠g爜锛堜笅杞芥柟寮忥級
-     *
-     * @param tableName 琛ㄥ悕绉�
-     * @return 鏁版嵁
-     */
-    @Override
-    public byte[] downloadCode(String tableName) {
-        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-        ZipOutputStream zip = new ZipOutputStream(outputStream);
-        generatorCode(tableName, zip);
-        IoUtil.close(zip);
-        return outputStream.toByteArray();
-    }
-
-    /**
-     * 鐢熸垚浠g爜锛堣嚜瀹氫箟璺緞锛�
-     *
-     * @param tableName 琛ㄥ悕绉�
-     */
-    @Override
-    public void generatorCode(String tableName) {
-        // 鏌ヨ琛ㄤ俊鎭�
-        GenTable table = baseMapper.selectGenTableByName(tableName);
-        // 璁剧疆涓婚敭鍒椾俊鎭�
-        setPkColumn(table);
-
-        VelocityInitializer.initVelocity();
-
-        VelocityContext context = VelocityUtils.prepareContext(table);
-
-        // 鑾峰彇妯℃澘鍒楄〃
-        List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
-        for (String template : templates) {
-            if (!StringUtils.containsAny(template, "sql.vm", "api.js.vm", "index.vue.vm", "index-tree.vue.vm")) {
-                // 娓叉煋妯℃澘
-                StringWriter sw = new StringWriter();
-                Template tpl = Velocity.getTemplate(template, Constants.UTF8);
-                tpl.merge(context, sw);
-                try {
-                    String path = getGenPath(table, template);
-                    FileUtils.writeUtf8String(sw.toString(), path);
-                } catch (Exception e) {
-                    throw new ServiceException("娓叉煋妯℃澘澶辫触锛岃〃鍚嶏細" + table.getTableName());
-                }
-            }
-        }
-    }
-
-    /**
-     * 鍚屾鏁版嵁搴�
-     *
-     * @param tableName 琛ㄥ悕绉�
-     */
-    @Transactional(rollbackFor = Exception.class)
-    @Override
-    public void synchDb(String tableName) {
-        GenTable table = baseMapper.selectGenTableByName(tableName);
-        List<GenTableColumn> tableColumns = table.getColumns();
-        Map<String, GenTableColumn> tableColumnMap = StreamUtils.toIdentityMap(tableColumns, GenTableColumn::getColumnName);
-
-        List<GenTableColumn> dbTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName);
-        if (CollUtil.isEmpty(dbTableColumns)) {
-            throw new ServiceException("鍚屾鏁版嵁澶辫触锛屽師琛ㄧ粨鏋勪笉瀛樺湪");
-        }
-        List<String> dbTableColumnNames = StreamUtils.toList(dbTableColumns, GenTableColumn::getColumnName);
-
-        List<GenTableColumn> saveColumns = new ArrayList<>();
-        dbTableColumns.forEach(column -> {
-            GenUtils.initColumnField(column, table);
-            if (tableColumnMap.containsKey(column.getColumnName())) {
-                GenTableColumn prevColumn = tableColumnMap.get(column.getColumnName());
-                column.setColumnId(prevColumn.getColumnId());
-                if (column.isList()) {
-                    // 濡傛灉鏄垪琛紝缁х画淇濈暀鏌ヨ鏂瑰紡/瀛楀吀绫诲瀷閫夐」
-                    column.setDictType(prevColumn.getDictType());
-                    column.setQueryType(prevColumn.getQueryType());
-                }
-                if (StringUtils.isNotEmpty(prevColumn.getIsRequired()) && !column.isPk()
-                    && (column.isInsert() || column.isEdit())
-                    && ((column.isUsableColumn()) || (!column.isSuperColumn()))) {
-                    // 濡傛灉鏄�(鏂板/淇敼&闈炰富閿�/闈炲拷鐣ュ強鐖跺睘鎬�)锛岀户缁繚鐣欏繀濉�/鏄剧ず绫诲瀷閫夐」
-                    column.setIsRequired(prevColumn.getIsRequired());
-                    column.setHtmlType(prevColumn.getHtmlType());
-                }
-            }
-            saveColumns.add(column);
-        });
-        if (CollUtil.isNotEmpty(saveColumns)) {
-            genTableColumnMapper.insertOrUpdateBatch(saveColumns);
-        }
-        List<GenTableColumn> delColumns = StreamUtils.filter(tableColumns, column -> !dbTableColumnNames.contains(column.getColumnName()));
-        if (CollUtil.isNotEmpty(delColumns)) {
-            List<Long> ids = StreamUtils.toList(delColumns, GenTableColumn::getColumnId);
-            genTableColumnMapper.deleteBatchIds(ids);
-        }
-    }
-
-    /**
-     * 鎵归噺鐢熸垚浠g爜锛堜笅杞芥柟寮忥級
-     *
-     * @param tableNames 琛ㄦ暟缁�
-     * @return 鏁版嵁
-     */
-    @Override
-    public byte[] downloadCode(String[] tableNames) {
-        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-        ZipOutputStream zip = new ZipOutputStream(outputStream);
-        for (String tableName : tableNames) {
-            generatorCode(tableName, zip);
-        }
-        IoUtil.close(zip);
-        return outputStream.toByteArray();
-    }
-
-    /**
-     * 鏌ヨ琛ㄤ俊鎭苟鐢熸垚浠g爜
-     */
-    private void generatorCode(String tableName, ZipOutputStream zip) {
-        // 鏌ヨ琛ㄤ俊鎭�
-        GenTable table = baseMapper.selectGenTableByName(tableName);
-        List<Long> menuIds = new ArrayList<>();
-        for (int i = 0; i < 6; i++) {
-            menuIds.add(identifierGenerator.nextId(null).longValue());
-        }
-        table.setMenuIds(menuIds);
-        // 璁剧疆涓婚敭鍒椾俊鎭�
-        setPkColumn(table);
-
-        VelocityInitializer.initVelocity();
-
-        VelocityContext context = VelocityUtils.prepareContext(table);
-
-        // 鑾峰彇妯℃澘鍒楄〃
-        List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
-        for (String template : templates) {
-            // 娓叉煋妯℃澘
-            StringWriter sw = new StringWriter();
-            Template tpl = Velocity.getTemplate(template, Constants.UTF8);
-            tpl.merge(context, sw);
-            try {
-                // 娣诲姞鍒皕ip
-                zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table)));
-                IoUtil.write(zip, StandardCharsets.UTF_8, false, sw.toString());
-                IoUtil.close(sw);
-                zip.flush();
-                zip.closeEntry();
-            } catch (IOException e) {
-                log.error("娓叉煋妯℃澘澶辫触锛岃〃鍚嶏細" + table.getTableName(), e);
-            }
-        }
-    }
-
-    /**
-     * 淇敼淇濆瓨鍙傛暟鏍¢獙
-     *
-     * @param genTable 涓氬姟淇℃伅
-     */
-    @Override
-    public void validateEdit(GenTable genTable) {
-        if (GenConstants.TPL_TREE.equals(genTable.getTplCategory())) {
-            String options = JsonUtils.toJsonString(genTable.getParams());
-            Dict paramsObj = JsonUtils.parseMap(options);
-            if (StringUtils.isEmpty(paramsObj.getStr(GenConstants.TREE_CODE))) {
-                throw new ServiceException("鏍戠紪鐮佸瓧娈典笉鑳戒负绌�");
-            } else if (StringUtils.isEmpty(paramsObj.getStr(GenConstants.TREE_PARENT_CODE))) {
-                throw new ServiceException("鏍戠埗缂栫爜瀛楁涓嶈兘涓虹┖");
-            } else if (StringUtils.isEmpty(paramsObj.getStr(GenConstants.TREE_NAME))) {
-                throw new ServiceException("鏍戝悕绉板瓧娈典笉鑳戒负绌�");
-            }
-        }
-    }
-
-    /**
-     * 璁剧疆涓婚敭鍒椾俊鎭�
-     *
-     * @param table 涓氬姟琛ㄤ俊鎭�
-     */
-    public void setPkColumn(GenTable table) {
-        for (GenTableColumn column : table.getColumns()) {
-            if (column.isPk()) {
-                table.setPkColumn(column);
-                break;
-            }
-        }
-        if (ObjectUtil.isNull(table.getPkColumn())) {
-            table.setPkColumn(table.getColumns().get(0));
-        }
-
-    }
-
-    /**
-     * 璁剧疆浠g爜鐢熸垚鍏朵粬閫夐」鍊�
-     *
-     * @param genTable 璁剧疆鍚庣殑鐢熸垚瀵硅薄
-     */
-    public void setTableFromOptions(GenTable genTable) {
-        Dict paramsObj = JsonUtils.parseMap(genTable.getOptions());
-        if (ObjectUtil.isNotNull(paramsObj)) {
-            String treeCode = paramsObj.getStr(GenConstants.TREE_CODE);
-            String treeParentCode = paramsObj.getStr(GenConstants.TREE_PARENT_CODE);
-            String treeName = paramsObj.getStr(GenConstants.TREE_NAME);
-            String parentMenuId = paramsObj.getStr(GenConstants.PARENT_MENU_ID);
-            String parentMenuName = paramsObj.getStr(GenConstants.PARENT_MENU_NAME);
-
-            genTable.setTreeCode(treeCode);
-            genTable.setTreeParentCode(treeParentCode);
-            genTable.setTreeName(treeName);
-            genTable.setParentMenuId(parentMenuId);
-            genTable.setParentMenuName(parentMenuName);
-        }
-    }
-
-    /**
-     * 鑾峰彇浠g爜鐢熸垚鍦板潃
-     *
-     * @param table    涓氬姟琛ㄤ俊鎭�
-     * @param template 妯℃澘鏂囦欢璺緞
-     * @return 鐢熸垚鍦板潃
-     */
-    public static String getGenPath(GenTable table, String template) {
-        String genPath = table.getGenPath();
-        if (StringUtils.equals(genPath, "/")) {
-            return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(template, table);
-        }
-        return genPath + File.separator + VelocityUtils.getFileName(template, table);
-    }
-}
-
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableService.java b/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableService.java
deleted file mode 100644
index 3e6727f..0000000
--- a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableService.java
+++ /dev/null
@@ -1,133 +0,0 @@
-package com.ruoyi.generator.service;
-
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.generator.domain.GenTable;
-import com.ruoyi.generator.domain.GenTableColumn;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * 涓氬姟 鏈嶅姟灞�
- *
- * @author Lion Li
- */
-public interface IGenTableService {
-
-    /**
-     * 鏌ヨ涓氬姟瀛楁鍒楄〃
-     *
-     * @param tableId 涓氬姟瀛楁缂栧彿
-     * @return 涓氬姟瀛楁闆嗗悎
-     */
-    List<GenTableColumn> selectGenTableColumnListByTableId(Long tableId);
-
-    /**
-     * 鏌ヨ涓氬姟鍒楄〃
-     *
-     * @param genTable 涓氬姟淇℃伅
-     * @return 涓氬姟闆嗗悎
-     */
-    TableDataInfo<GenTable> selectPageGenTableList(GenTable genTable, PageQuery pageQuery);
-
-    /**
-     * 鏌ヨ鎹簱鍒楄〃
-     *
-     * @param genTable 涓氬姟淇℃伅
-     * @return 鏁版嵁搴撹〃闆嗗悎
-     */
-    TableDataInfo<GenTable> selectPageDbTableList(GenTable genTable, PageQuery pageQuery);
-
-    /**
-     * 鏌ヨ鎹簱鍒楄〃
-     *
-     * @param tableNames 琛ㄥ悕绉扮粍
-     * @return 鏁版嵁搴撹〃闆嗗悎
-     */
-    List<GenTable> selectDbTableListByNames(String[] tableNames);
-
-    /**
-     * 鏌ヨ鎵�鏈夎〃淇℃伅
-     *
-     * @return 琛ㄤ俊鎭泦鍚�
-     */
-    List<GenTable> selectGenTableAll();
-
-    /**
-     * 鏌ヨ涓氬姟淇℃伅
-     *
-     * @param id 涓氬姟ID
-     * @return 涓氬姟淇℃伅
-     */
-    GenTable selectGenTableById(Long id);
-
-    /**
-     * 淇敼涓氬姟
-     *
-     * @param genTable 涓氬姟淇℃伅
-     * @return 缁撴灉
-     */
-    void updateGenTable(GenTable genTable);
-
-    /**
-     * 鍒犻櫎涓氬姟淇℃伅
-     *
-     * @param tableIds 闇�瑕佸垹闄ょ殑琛ㄦ暟鎹甀D
-     * @return 缁撴灉
-     */
-    void deleteGenTableByIds(Long[] tableIds);
-
-    /**
-     * 瀵煎叆琛ㄧ粨鏋�
-     *
-     * @param tableList 瀵煎叆琛ㄥ垪琛�
-     */
-    void importGenTable(List<GenTable> tableList);
-
-    /**
-     * 棰勮浠g爜
-     *
-     * @param tableId 琛ㄧ紪鍙�
-     * @return 棰勮鏁版嵁鍒楄〃
-     */
-    Map<String, String> previewCode(Long tableId);
-
-    /**
-     * 鐢熸垚浠g爜锛堜笅杞芥柟寮忥級
-     *
-     * @param tableName 琛ㄥ悕绉�
-     * @return 鏁版嵁
-     */
-    byte[] downloadCode(String tableName);
-
-    /**
-     * 鐢熸垚浠g爜锛堣嚜瀹氫箟璺緞锛�
-     *
-     * @param tableName 琛ㄥ悕绉�
-     * @return 鏁版嵁
-     */
-    void generatorCode(String tableName);
-
-    /**
-     * 鍚屾鏁版嵁搴�
-     *
-     * @param tableName 琛ㄥ悕绉�
-     */
-    void synchDb(String tableName);
-
-    /**
-     * 鎵归噺鐢熸垚浠g爜锛堜笅杞芥柟寮忥級
-     *
-     * @param tableNames 琛ㄦ暟缁�
-     * @return 鏁版嵁
-     */
-    byte[] downloadCode(String[] tableNames);
-
-    /**
-     * 淇敼淇濆瓨鍙傛暟鏍¢獙
-     *
-     * @param genTable 涓氬姟淇℃伅
-     */
-    void validateEdit(GenTable genTable);
-}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java b/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java
deleted file mode 100644
index 5a9286f..0000000
--- a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java
+++ /dev/null
@@ -1,233 +0,0 @@
-package com.ruoyi.generator.util;
-
-import com.ruoyi.generator.constant.GenConstants;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.satoken.utils.LoginHelper;
-import com.ruoyi.generator.config.GenConfig;
-import com.ruoyi.generator.domain.GenTable;
-import com.ruoyi.generator.domain.GenTableColumn;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import org.apache.commons.lang3.RegExUtils;
-
-import java.util.Arrays;
-
-/**
- * 浠g爜鐢熸垚鍣� 宸ュ叿绫�
- *
- * @author ruoyi
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class GenUtils {
-
-    /**
-     * 鍒濆鍖栬〃淇℃伅
-     */
-    public static void initTable(GenTable genTable, String operName) {
-        genTable.setClassName(convertClassName(genTable.getTableName()));
-        genTable.setPackageName(GenConfig.getPackageName());
-        genTable.setModuleName(getModuleName(GenConfig.getPackageName()));
-        genTable.setBusinessName(getBusinessName(genTable.getTableName()));
-        genTable.setFunctionName(replaceText(genTable.getTableComment()));
-        genTable.setFunctionAuthor(GenConfig.getAuthor());
-        genTable.setCreateBy(LoginHelper.getUserId());
-    }
-
-    /**
-     * 鍒濆鍖栧垪灞炴�у瓧娈�
-     */
-    public static void initColumnField(GenTableColumn column, GenTable table) {
-        String dataType = getDbType(column.getColumnType());
-        String columnName = column.getColumnName();
-        column.setTableId(table.getTableId());
-        column.setCreateBy(table.getCreateBy());
-        // 璁剧疆java瀛楁鍚�
-        column.setJavaField(StringUtils.toCamelCase(columnName));
-        // 璁剧疆榛樿绫诲瀷
-        column.setJavaType(GenConstants.TYPE_STRING);
-        column.setQueryType(GenConstants.QUERY_EQ);
-
-        if (arraysContains(GenConstants.COLUMNTYPE_STR, dataType) || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType)) {
-            // 瀛楃涓查暱搴﹁秴杩�500璁剧疆涓烘枃鏈煙
-            Integer columnLength = getColumnLength(column.getColumnType());
-            String htmlType = columnLength >= 500 || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType) ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT;
-            column.setHtmlType(htmlType);
-        } else if (arraysContains(GenConstants.COLUMNTYPE_TIME, dataType)) {
-            column.setJavaType(GenConstants.TYPE_DATE);
-            column.setHtmlType(GenConstants.HTML_DATETIME);
-        } else if (arraysContains(GenConstants.COLUMNTYPE_NUMBER, dataType)) {
-            column.setHtmlType(GenConstants.HTML_INPUT);
-
-            // 濡傛灉鏄诞鐐瑰瀷 缁熶竴鐢˙igDecimal
-            String[] str = StringUtils.split(StringUtils.substringBetween(column.getColumnType(), "(", ")"), StringUtils.SEPARATOR);
-            if (str != null && str.length == 2 && Integer.parseInt(str[1]) > 0) {
-                column.setJavaType(GenConstants.TYPE_BIGDECIMAL);
-            }
-            // 濡傛灉鏄暣褰�
-            else if (str != null && str.length == 1 && Integer.parseInt(str[0]) <= 10) {
-                column.setJavaType(GenConstants.TYPE_INTEGER);
-            }
-            // 闀挎暣褰�
-            else {
-                column.setJavaType(GenConstants.TYPE_LONG);
-            }
-        }
-
-        // BO瀵硅薄 榛樿鎻掑叆鍕鹃��
-        if (!arraysContains(GenConstants.COLUMNNAME_NOT_ADD, columnName) && !column.isPk()) {
-            column.setIsInsert(GenConstants.REQUIRE);
-        }
-        // BO瀵硅薄 榛樿缂栬緫鍕鹃��
-        if (!arraysContains(GenConstants.COLUMNNAME_NOT_EDIT, columnName)) {
-            column.setIsEdit(GenConstants.REQUIRE);
-        }
-        // BO瀵硅薄 榛樿鏄惁蹇呭~鍕鹃��
-        if (!arraysContains(GenConstants.COLUMNNAME_NOT_EDIT, columnName)) {
-            column.setIsRequired(GenConstants.REQUIRE);
-        }
-        // VO瀵硅薄 榛樿杩斿洖鍕鹃��
-        if (!arraysContains(GenConstants.COLUMNNAME_NOT_LIST, columnName)) {
-            column.setIsList(GenConstants.REQUIRE);
-        }
-        // BO瀵硅薄 榛樿鏌ヨ鍕鹃��
-        if (!arraysContains(GenConstants.COLUMNNAME_NOT_QUERY, columnName) && !column.isPk()) {
-            column.setIsQuery(GenConstants.REQUIRE);
-        }
-
-        // 鏌ヨ瀛楁绫诲瀷
-        if (StringUtils.endsWithIgnoreCase(columnName, "name")) {
-            column.setQueryType(GenConstants.QUERY_LIKE);
-        }
-        // 鐘舵�佸瓧娈佃缃崟閫夋
-        if (StringUtils.endsWithIgnoreCase(columnName, "status")) {
-            column.setHtmlType(GenConstants.HTML_RADIO);
-        }
-        // 绫诲瀷&鎬у埆瀛楁璁剧疆涓嬫媺妗�
-        else if (StringUtils.endsWithIgnoreCase(columnName, "type")
-            || StringUtils.endsWithIgnoreCase(columnName, "sex")) {
-            column.setHtmlType(GenConstants.HTML_SELECT);
-        }
-        // 鍥剧墖瀛楁璁剧疆鍥剧墖涓婁紶鎺т欢
-        else if (StringUtils.endsWithIgnoreCase(columnName, "image")) {
-            column.setHtmlType(GenConstants.HTML_IMAGE_UPLOAD);
-        }
-        // 鏂囦欢瀛楁璁剧疆鏂囦欢涓婁紶鎺т欢
-        else if (StringUtils.endsWithIgnoreCase(columnName, "file")) {
-            column.setHtmlType(GenConstants.HTML_FILE_UPLOAD);
-        }
-        // 鍐呭瀛楁璁剧疆瀵屾枃鏈帶浠�
-        else if (StringUtils.endsWithIgnoreCase(columnName, "content")) {
-            column.setHtmlType(GenConstants.HTML_EDITOR);
-        }
-    }
-
-    /**
-     * 鏍¢獙鏁扮粍鏄惁鍖呭惈鎸囧畾鍊�
-     *
-     * @param arr         鏁扮粍
-     * @param targetValue 鍊�
-     * @return 鏄惁鍖呭惈
-     */
-    public static boolean arraysContains(String[] arr, String targetValue) {
-        return Arrays.asList(arr).contains(targetValue);
-    }
-
-    /**
-     * 鑾峰彇妯″潡鍚�
-     *
-     * @param packageName 鍖呭悕
-     * @return 妯″潡鍚�
-     */
-    public static String getModuleName(String packageName) {
-        int lastIndex = packageName.lastIndexOf(".");
-        int nameLength = packageName.length();
-        return StringUtils.substring(packageName, lastIndex + 1, nameLength);
-    }
-
-    /**
-     * 鑾峰彇涓氬姟鍚�
-     *
-     * @param tableName 琛ㄥ悕
-     * @return 涓氬姟鍚�
-     */
-    public static String getBusinessName(String tableName) {
-        int firstIndex = tableName.indexOf("_");
-        int nameLength = tableName.length();
-        String businessName = StringUtils.substring(tableName, firstIndex + 1, nameLength);
-        businessName = StringUtils.toCamelCase(businessName);
-        return businessName;
-    }
-
-    /**
-     * 琛ㄥ悕杞崲鎴怞ava绫诲悕
-     *
-     * @param tableName 琛ㄥ悕绉�
-     * @return 绫诲悕
-     */
-    public static String convertClassName(String tableName) {
-        boolean autoRemovePre = GenConfig.getAutoRemovePre();
-        String tablePrefix = GenConfig.getTablePrefix();
-        if (autoRemovePre && StringUtils.isNotEmpty(tablePrefix)) {
-            String[] searchList = StringUtils.split(tablePrefix, StringUtils.SEPARATOR);
-            tableName = replaceFirst(tableName, searchList);
-        }
-        return StringUtils.convertToCamelCase(tableName);
-    }
-
-    /**
-     * 鎵归噺鏇挎崲鍓嶇紑
-     *
-     * @param replacementm 鏇挎崲鍊�
-     * @param searchList   鏇挎崲鍒楄〃
-     * @return
-     */
-    public static String replaceFirst(String replacementm, String[] searchList) {
-        String text = replacementm;
-        for (String searchString : searchList) {
-            if (replacementm.startsWith(searchString)) {
-                text = replacementm.replaceFirst(searchString, "");
-                break;
-            }
-        }
-        return text;
-    }
-
-    /**
-     * 鍏抽敭瀛楁浛鎹�
-     *
-     * @param text 闇�瑕佽鏇挎崲鐨勫悕瀛�
-     * @return 鏇挎崲鍚庣殑鍚嶅瓧
-     */
-    public static String replaceText(String text) {
-        return RegExUtils.replaceAll(text, "(?:琛▅鑻ヤ緷)", "");
-    }
-
-    /**
-     * 鑾峰彇鏁版嵁搴撶被鍨嬪瓧娈�
-     *
-     * @param columnType 鍒楃被鍨�
-     * @return 鎴彇鍚庣殑鍒楃被鍨�
-     */
-    public static String getDbType(String columnType) {
-        if (StringUtils.indexOf(columnType, '(') > 0) {
-            return StringUtils.substringBefore(columnType, "(");
-        } else {
-            return columnType;
-        }
-    }
-
-    /**
-     * 鑾峰彇瀛楁闀垮害
-     *
-     * @param columnType 鍒楃被鍨�
-     * @return 鎴彇鍚庣殑鍒楃被鍨�
-     */
-    public static Integer getColumnLength(String columnType) {
-        if (StringUtils.indexOf(columnType, '(') > 0) {
-            String length = StringUtils.substringBetween(columnType, "(", ")");
-            return Integer.valueOf(length);
-        } else {
-            return 0;
-        }
-    }
-}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java b/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java
deleted file mode 100644
index 045e303..0000000
--- a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.ruoyi.generator.util;
-
-import com.ruoyi.common.core.constant.Constants;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import org.apache.velocity.app.Velocity;
-
-import java.util.Properties;
-
-/**
- * VelocityEngine宸ュ巶
- *
- * @author ruoyi
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class VelocityInitializer {
-
-    /**
-     * 鍒濆鍖杤m鏂规硶
-     */
-    public static void initVelocity() {
-        Properties p = new Properties();
-        try {
-            // 鍔犺浇classpath鐩綍涓嬬殑vm鏂囦欢
-            p.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
-            // 瀹氫箟瀛楃闆�
-            p.setProperty(Velocity.INPUT_ENCODING, Constants.UTF8);
-            // 鍒濆鍖朧elocity寮曟搸锛屾寚瀹氶厤缃甈roperties
-            Velocity.init(p);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java b/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java
deleted file mode 100644
index b1557fc..0000000
--- a/ruoyi-modules/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java
+++ /dev/null
@@ -1,335 +0,0 @@
-package com.ruoyi.generator.util;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.convert.Convert;
-import cn.hutool.core.lang.Dict;
-import com.ruoyi.generator.constant.GenConstants;
-import com.ruoyi.common.core.utils.DateUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.json.utils.JsonUtils;
-import com.ruoyi.common.mybatis.helper.DataBaseHelper;
-import com.ruoyi.generator.domain.GenTable;
-import com.ruoyi.generator.domain.GenTableColumn;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import org.apache.velocity.VelocityContext;
-
-import java.util.*;
-
-/**
- * 妯℃澘澶勭悊宸ュ叿绫�
- *
- * @author ruoyi
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class VelocityUtils {
-
-    /**
-     * 椤圭洰绌洪棿璺緞
-     */
-    private static final String PROJECT_PATH = "main/java";
-
-    /**
-     * mybatis绌洪棿璺緞
-     */
-    private static final String MYBATIS_PATH = "main/resources/mapper";
-
-    /**
-     * 榛樿涓婄骇鑿滃崟锛岀郴缁熷伐鍏�
-     */
-    private static final String DEFAULT_PARENT_MENU_ID = "3";
-
-    /**
-     * 璁剧疆妯℃澘鍙橀噺淇℃伅
-     *
-     * @return 妯℃澘鍒楄〃
-     */
-    public static VelocityContext prepareContext(GenTable genTable) {
-        String moduleName = genTable.getModuleName();
-        String businessName = genTable.getBusinessName();
-        String packageName = genTable.getPackageName();
-        String tplCategory = genTable.getTplCategory();
-        String functionName = genTable.getFunctionName();
-
-        VelocityContext velocityContext = new VelocityContext();
-        velocityContext.put("tplCategory", genTable.getTplCategory());
-        velocityContext.put("tableName", genTable.getTableName());
-        velocityContext.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "銆愯濉啓鍔熻兘鍚嶇О銆�");
-        velocityContext.put("ClassName", genTable.getClassName());
-        velocityContext.put("className", StringUtils.uncapitalize(genTable.getClassName()));
-        velocityContext.put("moduleName", genTable.getModuleName());
-        velocityContext.put("BusinessName", StringUtils.capitalize(genTable.getBusinessName()));
-        velocityContext.put("businessName", genTable.getBusinessName());
-        velocityContext.put("basePackage", getPackagePrefix(packageName));
-        velocityContext.put("packageName", packageName);
-        velocityContext.put("author", genTable.getFunctionAuthor());
-        velocityContext.put("datetime", DateUtils.getDate());
-        velocityContext.put("pkColumn", genTable.getPkColumn());
-        velocityContext.put("importList", getImportList(genTable));
-        velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName));
-        velocityContext.put("columns", genTable.getColumns());
-        velocityContext.put("table", genTable);
-        velocityContext.put("dicts", getDicts(genTable));
-        setMenuVelocityContext(velocityContext, genTable);
-        if (GenConstants.TPL_TREE.equals(tplCategory)) {
-            setTreeVelocityContext(velocityContext, genTable);
-        }
-        return velocityContext;
-    }
-
-    public static void setMenuVelocityContext(VelocityContext context, GenTable genTable) {
-        String options = genTable.getOptions();
-        Dict paramsObj = JsonUtils.parseMap(options);
-        String parentMenuId = getParentMenuId(paramsObj);
-        context.put("parentMenuId", parentMenuId);
-    }
-
-    public static void setTreeVelocityContext(VelocityContext context, GenTable genTable) {
-        String options = genTable.getOptions();
-        Dict paramsObj = JsonUtils.parseMap(options);
-        String treeCode = getTreecode(paramsObj);
-        String treeParentCode = getTreeParentCode(paramsObj);
-        String treeName = getTreeName(paramsObj);
-
-        context.put("treeCode", treeCode);
-        context.put("treeParentCode", treeParentCode);
-        context.put("treeName", treeName);
-        context.put("expandColumn", getExpandColumn(genTable));
-        if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) {
-            context.put("tree_parent_code", paramsObj.get(GenConstants.TREE_PARENT_CODE));
-        }
-        if (paramsObj.containsKey(GenConstants.TREE_NAME)) {
-            context.put("tree_name", paramsObj.get(GenConstants.TREE_NAME));
-        }
-    }
-
-    /**
-     * 鑾峰彇妯℃澘淇℃伅
-     *
-     * @return 妯℃澘鍒楄〃
-     */
-    public static List<String> getTemplateList(String tplCategory) {
-        List<String> templates = new ArrayList<String>();
-        templates.add("vm/java/domain.java.vm");
-        templates.add("vm/java/vo.java.vm");
-        templates.add("vm/java/bo.java.vm");
-        templates.add("vm/java/mapper.java.vm");
-        templates.add("vm/java/service.java.vm");
-        templates.add("vm/java/serviceImpl.java.vm");
-        templates.add("vm/java/controller.java.vm");
-        templates.add("vm/xml/mapper.xml.vm");
-        if (DataBaseHelper.isOracle()) {
-            templates.add("vm/sql/oracle/sql.vm");
-        } else if (DataBaseHelper.isPostgerSql()) {
-            templates.add("vm/sql/postgres/sql.vm");
-        } else if (DataBaseHelper.isSqlServer()) {
-            templates.add("vm/sql/sqlserver/sql.vm");
-        } else {
-            templates.add("vm/sql/sql.vm");
-        }
-        templates.add("vm/js/api.js.vm");
-        if (GenConstants.TPL_CRUD.equals(tplCategory)) {
-            templates.add("vm/vue/index.vue.vm");
-        } else if (GenConstants.TPL_TREE.equals(tplCategory)) {
-            templates.add("vm/vue/index-tree.vue.vm");
-        }
-        return templates;
-    }
-
-    /**
-     * 鑾峰彇鏂囦欢鍚�
-     */
-    public static String getFileName(String template, GenTable genTable) {
-        // 鏂囦欢鍚嶇О
-        String fileName = "";
-        // 鍖呰矾寰�
-        String packageName = genTable.getPackageName();
-        // 妯″潡鍚�
-        String moduleName = genTable.getModuleName();
-        // 澶у啓绫诲悕
-        String className = genTable.getClassName();
-        // 涓氬姟鍚嶇О
-        String businessName = genTable.getBusinessName();
-
-        String javaPath = PROJECT_PATH + "/" + StringUtils.replace(packageName, ".", "/");
-        String mybatisPath = MYBATIS_PATH + "/" + moduleName;
-        String vuePath = "vue";
-
-        if (template.contains("domain.java.vm")) {
-            fileName = StringUtils.format("{}/domain/{}.java", javaPath, className);
-        }
-        if (template.contains("vo.java.vm")) {
-            fileName = StringUtils.format("{}/domain/vo/{}Vo.java", javaPath, className);
-        }
-        if (template.contains("bo.java.vm")) {
-            fileName = StringUtils.format("{}/domain/bo/{}Bo.java", javaPath, className);
-        }
-        if (template.contains("mapper.java.vm")) {
-            fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className);
-        } else if (template.contains("service.java.vm")) {
-            fileName = StringUtils.format("{}/service/I{}Service.java", javaPath, className);
-        } else if (template.contains("serviceImpl.java.vm")) {
-            fileName = StringUtils.format("{}/service/impl/{}ServiceImpl.java", javaPath, className);
-        } else if (template.contains("controller.java.vm")) {
-            fileName = StringUtils.format("{}/controller/{}Controller.java", javaPath, className);
-        } else if (template.contains("mapper.xml.vm")) {
-            fileName = StringUtils.format("{}/{}Mapper.xml", mybatisPath, className);
-        } else if (template.contains("sql.vm")) {
-            fileName = businessName + "Menu.sql";
-        } else if (template.contains("api.js.vm")) {
-            fileName = StringUtils.format("{}/api/{}/{}.js", vuePath, moduleName, businessName);
-        } else if (template.contains("index.vue.vm")) {
-            fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName);
-        } else if (template.contains("index-tree.vue.vm")) {
-            fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName);
-        }
-        return fileName;
-    }
-
-    /**
-     * 鑾峰彇鍖呭墠缂�
-     *
-     * @param packageName 鍖呭悕绉�
-     * @return 鍖呭墠缂�鍚嶇О
-     */
-    public static String getPackagePrefix(String packageName) {
-        int lastIndex = packageName.lastIndexOf(".");
-        return StringUtils.substring(packageName, 0, lastIndex);
-    }
-
-    /**
-     * 鏍规嵁鍒楃被鍨嬭幏鍙栧鍏ュ寘
-     *
-     * @param genTable 涓氬姟琛ㄥ璞�
-     * @return 杩斿洖闇�瑕佸鍏ョ殑鍖呭垪琛�
-     */
-    public static HashSet<String> getImportList(GenTable genTable) {
-        List<GenTableColumn> columns = genTable.getColumns();
-        HashSet<String> importList = new HashSet<String>();
-        for (GenTableColumn column : columns) {
-            if (!column.isSuperColumn() && GenConstants.TYPE_DATE.equals(column.getJavaType())) {
-                importList.add("java.util.Date");
-                importList.add("com.fasterxml.jackson.annotation.JsonFormat");
-            } else if (!column.isSuperColumn() && GenConstants.TYPE_BIGDECIMAL.equals(column.getJavaType())) {
-                importList.add("java.math.BigDecimal");
-            }
-        }
-        return importList;
-    }
-
-    /**
-     * 鏍规嵁鍒楃被鍨嬭幏鍙栧瓧鍏哥粍
-     *
-     * @param genTable 涓氬姟琛ㄥ璞�
-     * @return 杩斿洖瀛楀吀缁�
-     */
-    public static String getDicts(GenTable genTable) {
-        List<GenTableColumn> columns = genTable.getColumns();
-        Set<String> dicts = new HashSet<>();
-        addDicts(dicts, columns);
-        return StringUtils.join(dicts, ", ");
-    }
-
-    /**
-     * 娣诲姞瀛楀吀鍒楄〃
-     *
-     * @param dicts 瀛楀吀鍒楄〃
-     * @param columns 鍒楅泦鍚�
-     */
-    public static void addDicts(Set<String> dicts, List<GenTableColumn> columns) {
-        for (GenTableColumn column : columns) {
-            if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny(
-                column.getHtmlType(),
-                new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX })) {
-                dicts.add("'" + column.getDictType() + "'");
-            }
-        }
-    }
-
-    /**
-     * 鑾峰彇鏉冮檺鍓嶇紑
-     *
-     * @param moduleName   妯″潡鍚嶇О
-     * @param businessName 涓氬姟鍚嶇О
-     * @return 杩斿洖鏉冮檺鍓嶇紑
-     */
-    public static String getPermissionPrefix(String moduleName, String businessName) {
-        return StringUtils.format("{}:{}", moduleName, businessName);
-    }
-
-    /**
-     * 鑾峰彇涓婄骇鑿滃崟ID瀛楁
-     *
-     * @param paramsObj 鐢熸垚鍏朵粬閫夐」
-     * @return 涓婄骇鑿滃崟ID瀛楁
-     */
-    public static String getParentMenuId(Dict paramsObj) {
-        if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.PARENT_MENU_ID)
-            && StringUtils.isNotEmpty(paramsObj.getStr(GenConstants.PARENT_MENU_ID))) {
-            return paramsObj.getStr(GenConstants.PARENT_MENU_ID);
-        }
-        return DEFAULT_PARENT_MENU_ID;
-    }
-
-    /**
-     * 鑾峰彇鏍戠紪鐮�
-     *
-     * @param paramsObj 鐢熸垚鍏朵粬閫夐」
-     * @return 鏍戠紪鐮�
-     */
-    public static String getTreecode(Map<String, Object> paramsObj) {
-        if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_CODE)) {
-            return StringUtils.toCamelCase(Convert.toStr(paramsObj.get(GenConstants.TREE_CODE)));
-        }
-        return StringUtils.EMPTY;
-    }
-
-    /**
-     * 鑾峰彇鏍戠埗缂栫爜
-     *
-     * @param paramsObj 鐢熸垚鍏朵粬閫夐」
-     * @return 鏍戠埗缂栫爜
-     */
-    public static String getTreeParentCode(Dict paramsObj) {
-        if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) {
-            return StringUtils.toCamelCase(paramsObj.getStr(GenConstants.TREE_PARENT_CODE));
-        }
-        return StringUtils.EMPTY;
-    }
-
-    /**
-     * 鑾峰彇鏍戝悕绉�
-     *
-     * @param paramsObj 鐢熸垚鍏朵粬閫夐」
-     * @return 鏍戝悕绉�
-     */
-    public static String getTreeName(Dict paramsObj) {
-        if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_NAME)) {
-            return StringUtils.toCamelCase(paramsObj.getStr(GenConstants.TREE_NAME));
-        }
-        return StringUtils.EMPTY;
-    }
-
-    /**
-     * 鑾峰彇闇�瑕佸湪鍝竴鍒椾笂闈㈡樉绀哄睍寮�鎸夐挳
-     *
-     * @param genTable 涓氬姟琛ㄥ璞�
-     * @return 灞曞紑鎸夐挳鍒楀簭鍙�
-     */
-    public static int getExpandColumn(GenTable genTable) {
-        String options = genTable.getOptions();
-        Dict paramsObj = JsonUtils.parseMap(options);
-        String treeName = paramsObj.getStr(GenConstants.TREE_NAME);
-        int num = 0;
-        for (GenTableColumn column : genTable.getColumns()) {
-            if (column.isList()) {
-                num++;
-                String columnName = column.getColumnName();
-                if (columnName.equals(treeName)) {
-                    break;
-                }
-            }
-        }
-        return num;
-    }
-}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/config/GenConfig.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/config/GenConfig.java
new file mode 100644
index 0000000..b29f8c9
--- /dev/null
+++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/config/GenConfig.java
@@ -0,0 +1,73 @@
+package org.dromara.generator.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.stereotype.Component;
+
+/**
+ * 璇诲彇浠g爜鐢熸垚鐩稿叧閰嶇疆
+ *
+ * @author ruoyi
+ */
+@Component
+@ConfigurationProperties(prefix = "gen")
+@PropertySource(value = {"classpath:generator.yml"}, encoding = "UTF-8")
+public class GenConfig {
+
+    /**
+     * 浣滆��
+     */
+    public static String author;
+
+    /**
+     * 鐢熸垚鍖呰矾寰�
+     */
+    public static String packageName;
+
+    /**
+     * 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸false
+     */
+    public static boolean autoRemovePre;
+
+    /**
+     * 琛ㄥ墠缂�(绫诲悕涓嶄細鍖呭惈琛ㄥ墠缂�)
+     */
+    public static String tablePrefix;
+
+    public static String getAuthor() {
+        return author;
+    }
+
+    @Value("${author}")
+    public void setAuthor(String author) {
+        GenConfig.author = author;
+    }
+
+    public static String getPackageName() {
+        return packageName;
+    }
+
+    @Value("${packageName}")
+    public void setPackageName(String packageName) {
+        GenConfig.packageName = packageName;
+    }
+
+    public static boolean getAutoRemovePre() {
+        return autoRemovePre;
+    }
+
+    @Value("${autoRemovePre}")
+    public void setAutoRemovePre(boolean autoRemovePre) {
+        GenConfig.autoRemovePre = autoRemovePre;
+    }
+
+    public static String getTablePrefix() {
+        return tablePrefix;
+    }
+
+    @Value("${tablePrefix}")
+    public void setTablePrefix(String tablePrefix) {
+        GenConfig.tablePrefix = tablePrefix;
+    }
+}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/constant/GenConstants.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/constant/GenConstants.java
new file mode 100644
index 0000000..c345f22
--- /dev/null
+++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/constant/GenConstants.java
@@ -0,0 +1,186 @@
+package org.dromara.generator.constant;
+
+/**
+ * 浠g爜鐢熸垚閫氱敤甯搁噺
+ *
+ * @author ruoyi
+ */
+public interface GenConstants {
+    /**
+     * 鍗曡〃锛堝鍒犳敼鏌ワ級
+     */
+    String TPL_CRUD = "crud";
+
+    /**
+     * 鏍戣〃锛堝鍒犳敼鏌ワ級
+     */
+    String TPL_TREE = "tree";
+
+    /**
+     * 鏍戠紪鐮佸瓧娈�
+     */
+    String TREE_CODE = "treeCode";
+
+    /**
+     * 鏍戠埗缂栫爜瀛楁
+     */
+    String TREE_PARENT_CODE = "treeParentCode";
+
+    /**
+     * 鏍戝悕绉板瓧娈�
+     */
+    String TREE_NAME = "treeName";
+
+    /**
+     * 涓婄骇鑿滃崟ID瀛楁
+     */
+    String PARENT_MENU_ID = "parentMenuId";
+
+    /**
+     * 涓婄骇鑿滃崟鍚嶇О瀛楁
+     */
+    String PARENT_MENU_NAME = "parentMenuName";
+
+    /**
+     * 鏁版嵁搴撳瓧绗︿覆绫诲瀷
+     */
+    String[] COLUMNTYPE_STR = {"char", "varchar", "enum", "set", "nchar", "nvarchar", "varchar2", "nvarchar2"};
+
+    /**
+     * 鏁版嵁搴撴枃鏈被鍨�
+     */
+    String[] COLUMNTYPE_TEXT = {"tinytext", "text", "mediumtext", "longtext", "binary", "varbinary", "blob",
+        "ntext", "image", "bytea"};
+
+    /**
+     * 鏁版嵁搴撴椂闂寸被鍨�
+     */
+    String[] COLUMNTYPE_TIME = {"datetime", "time", "date", "timestamp", "year", "interval",
+        "smalldatetime", "datetime2", "datetimeoffset"};
+
+    /**
+     * 鏁版嵁搴撴暟瀛楃被鍨�
+     */
+    String[] COLUMNTYPE_NUMBER = {"tinyint", "smallint", "mediumint", "int", "number", "integer",
+        "bit", "bigint", "float", "double", "decimal", "numeric", "real", "double precision",
+        "smallserial", "serial", "bigserial", "money", "smallmoney"};
+
+    /**
+     * BO瀵硅薄 涓嶉渶瑕佹坊鍔犲瓧娈�
+     */
+    String[] COLUMNNAME_NOT_ADD = {"create_dept", "create_by", "create_time", "del_flag", "update_by",
+        "update_time", "version", "tenant_id"};
+
+    /**
+     * BO瀵硅薄 涓嶉渶瑕佺紪杈戝瓧娈�
+     */
+    String[] COLUMNNAME_NOT_EDIT = {"create_dept", "create_by", "create_time", "del_flag", "update_by",
+        "update_time", "version", "tenant_id"};
+
+    /**
+     * VO瀵硅薄 涓嶉渶瑕佽繑鍥炲瓧娈�
+     */
+    String[] COLUMNNAME_NOT_LIST = {"create_dept", "create_by", "create_time", "del_flag", "update_by",
+        "update_time", "version", "tenant_id"};
+
+    /**
+     * BO瀵硅薄 涓嶉渶瑕佹煡璇㈠瓧娈�
+     */
+    String[] COLUMNNAME_NOT_QUERY = {"id", "create_dept", "create_by", "create_time", "del_flag", "update_by",
+        "update_time", "remark", "version", "tenant_id"};
+
+    /**
+     * Entity鍩虹被瀛楁
+     */
+    String[] BASE_ENTITY = {"createDept", "createBy", "createTime", "updateBy", "updateTime", "tenantId"};
+
+    /**
+     * 鏂囨湰妗�
+     */
+    String HTML_INPUT = "input";
+
+    /**
+     * 鏂囨湰鍩�
+     */
+    String HTML_TEXTAREA = "textarea";
+
+    /**
+     * 涓嬫媺妗�
+     */
+    String HTML_SELECT = "select";
+
+    /**
+     * 鍗曢�夋
+     */
+    String HTML_RADIO = "radio";
+
+    /**
+     * 澶嶉�夋
+     */
+    String HTML_CHECKBOX = "checkbox";
+
+    /**
+     * 鏃ユ湡鎺т欢
+     */
+    String HTML_DATETIME = "datetime";
+
+    /**
+     * 鍥剧墖涓婁紶鎺т欢
+     */
+    String HTML_IMAGE_UPLOAD = "imageUpload";
+
+    /**
+     * 鏂囦欢涓婁紶鎺т欢
+     */
+    String HTML_FILE_UPLOAD = "fileUpload";
+
+    /**
+     * 瀵屾枃鏈帶浠�
+     */
+    String HTML_EDITOR = "editor";
+
+    /**
+     * 瀛楃涓茬被鍨�
+     */
+    String TYPE_STRING = "String";
+
+    /**
+     * 鏁村瀷
+     */
+    String TYPE_INTEGER = "Integer";
+
+    /**
+     * 闀挎暣鍨�
+     */
+    String TYPE_LONG = "Long";
+
+    /**
+     * 娴偣鍨�
+     */
+    String TYPE_DOUBLE = "Double";
+
+    /**
+     * 楂樼簿搴﹁绠楃被鍨�
+     */
+    String TYPE_BIGDECIMAL = "BigDecimal";
+
+    /**
+     * 鏃堕棿绫诲瀷
+     */
+    String TYPE_DATE = "Date";
+
+    /**
+     * 妯$硦鏌ヨ
+     */
+    String QUERY_LIKE = "LIKE";
+
+    /**
+     * 鐩哥瓑鏌ヨ
+     */
+    String QUERY_EQ = "EQ";
+
+    /**
+     * 闇�瑕�
+     */
+    String REQUIRE = "1";
+}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/controller/GenController.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/controller/GenController.java
new file mode 100644
index 0000000..32133c1
--- /dev/null
+++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/controller/GenController.java
@@ -0,0 +1,207 @@
+package org.dromara.generator.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.io.IoUtil;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.generator.domain.GenTable;
+import org.dromara.generator.domain.GenTableColumn;
+import org.dromara.generator.service.IGenTableService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import jakarta.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 浠g爜鐢熸垚 鎿嶄綔澶勭悊
+ *
+ * @author Lion Li
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/tool/gen")
+public class GenController extends BaseController {
+
+    private final IGenTableService genTableService;
+
+    /**
+     * 鏌ヨ浠g爜鐢熸垚鍒楄〃
+     */
+    @SaCheckPermission("tool:gen:list")
+    @GetMapping("/list")
+    public TableDataInfo<GenTable> genList(GenTable genTable, PageQuery pageQuery) {
+        return genTableService.selectPageGenTableList(genTable, pageQuery);
+    }
+
+    /**
+     * 淇敼浠g爜鐢熸垚涓氬姟
+     *
+     * @param tableId 琛↖D
+     */
+    @SaCheckPermission("tool:gen:query")
+    @GetMapping(value = "/{tableId}")
+    public R<Map<String, Object>> getInfo(@PathVariable Long tableId) {
+        GenTable table = genTableService.selectGenTableById(tableId);
+        List<GenTable> tables = genTableService.selectGenTableAll();
+        List<GenTableColumn> list = genTableService.selectGenTableColumnListByTableId(tableId);
+        Map<String, Object> map = new HashMap<String, Object>();
+        map.put("info", table);
+        map.put("rows", list);
+        map.put("tables", tables);
+        return R.ok(map);
+    }
+
+    /**
+     * 鏌ヨ鏁版嵁搴撳垪琛�
+     */
+    @SaCheckPermission("tool:gen:list")
+    @GetMapping("/db/list")
+    public TableDataInfo<GenTable> dataList(GenTable genTable, PageQuery pageQuery) {
+        return genTableService.selectPageDbTableList(genTable, pageQuery);
+    }
+
+    /**
+     * 鏌ヨ鏁版嵁琛ㄥ瓧娈靛垪琛�
+     *
+     * @param tableId 琛↖D
+     */
+    @SaCheckPermission("tool:gen:list")
+    @GetMapping(value = "/column/{tableId}")
+    public TableDataInfo<GenTableColumn> columnList(Long tableId) {
+        TableDataInfo<GenTableColumn> dataInfo = new TableDataInfo<>();
+        List<GenTableColumn> list = genTableService.selectGenTableColumnListByTableId(tableId);
+        dataInfo.setRows(list);
+        dataInfo.setTotal(list.size());
+        return dataInfo;
+    }
+
+    /**
+     * 瀵煎叆琛ㄧ粨鏋勶紙淇濆瓨锛�
+     *
+     * @param tables 琛ㄥ悕涓�
+     */
+    @SaCheckPermission("tool:gen:import")
+    @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.IMPORT)
+    @PostMapping("/importTable")
+    public R<Void> importTableSave(String tables) {
+        String[] tableNames = Convert.toStrArray(tables);
+        // 鏌ヨ琛ㄤ俊鎭�
+        List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames);
+        genTableService.importGenTable(tableList);
+        return R.ok();
+    }
+
+    /**
+     * 淇敼淇濆瓨浠g爜鐢熸垚涓氬姟
+     */
+    @SaCheckPermission("tool:gen:edit")
+    @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public R<Void> editSave(@Validated @RequestBody GenTable genTable) {
+        genTableService.validateEdit(genTable);
+        genTableService.updateGenTable(genTable);
+        return R.ok();
+    }
+
+    /**
+     * 鍒犻櫎浠g爜鐢熸垚
+     *
+     * @param tableIds 琛↖D涓�
+     */
+    @SaCheckPermission("tool:gen:remove")
+    @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{tableIds}")
+    public R<Void> remove(@PathVariable Long[] tableIds) {
+        genTableService.deleteGenTableByIds(tableIds);
+        return R.ok();
+    }
+
+    /**
+     * 棰勮浠g爜
+     *
+     * @param tableId 琛↖D
+     */
+    @SaCheckPermission("tool:gen:preview")
+    @GetMapping("/preview/{tableId}")
+    public R<Map<String, String>> preview(@PathVariable("tableId") Long tableId) throws IOException {
+        Map<String, String> dataMap = genTableService.previewCode(tableId);
+        return R.ok(dataMap);
+    }
+
+    /**
+     * 鐢熸垚浠g爜锛堜笅杞芥柟寮忥級
+     *
+     * @param tableName 琛ㄥ悕
+     */
+    @SaCheckPermission("tool:gen:code")
+    @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.GENCODE)
+    @GetMapping("/download/{tableName}")
+    public void download(HttpServletResponse response, @PathVariable("tableName") String tableName) throws IOException {
+        byte[] data = genTableService.downloadCode(tableName);
+        genCode(response, data);
+    }
+
+    /**
+     * 鐢熸垚浠g爜锛堣嚜瀹氫箟璺緞锛�
+     *
+     * @param tableName 琛ㄥ悕
+     */
+    @SaCheckPermission("tool:gen:code")
+    @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.GENCODE)
+    @GetMapping("/genCode/{tableName}")
+    public R<Void> genCode(@PathVariable("tableName") String tableName) {
+        genTableService.generatorCode(tableName);
+        return R.ok();
+    }
+
+    /**
+     * 鍚屾鏁版嵁搴�
+     *
+     * @param tableName 琛ㄥ悕
+     */
+    @SaCheckPermission("tool:gen:edit")
+    @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.UPDATE)
+    @GetMapping("/synchDb/{tableName}")
+    public R<Void> synchDb(@PathVariable("tableName") String tableName) {
+        genTableService.synchDb(tableName);
+        return R.ok();
+    }
+
+    /**
+     * 鎵归噺鐢熸垚浠g爜
+     *
+     * @param tables 琛ㄥ悕涓�
+     */
+    @SaCheckPermission("tool:gen:code")
+    @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.GENCODE)
+    @GetMapping("/batchGenCode")
+    public void batchGenCode(HttpServletResponse response, String tables) throws IOException {
+        String[] tableNames = Convert.toStrArray(tables);
+        byte[] data = genTableService.downloadCode(tableNames);
+        genCode(response, data);
+    }
+
+    /**
+     * 鐢熸垚zip鏂囦欢
+     */
+    private void genCode(HttpServletResponse response, byte[] data) throws IOException {
+        response.reset();
+        response.addHeader("Access-Control-Allow-Origin", "*");
+        response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
+        response.setHeader("Content-Disposition", "attachment; filename=\"ruoyi.zip\"");
+        response.addHeader("Content-Length", "" + data.length);
+        response.setContentType("application/octet-stream; charset=UTF-8");
+        IoUtil.write(response.getOutputStream(), false, data);
+    }
+}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/domain/GenTable.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/domain/GenTable.java
new file mode 100644
index 0000000..944fd2e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/domain/GenTable.java
@@ -0,0 +1,190 @@
+package org.dromara.generator.domain;
+
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.generator.constant.GenConstants;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+/**
+ * 涓氬姟琛� gen_table
+ *
+ * @author Lion Li
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("gen_table")
+public class GenTable extends BaseEntity {
+
+    /**
+     * 缂栧彿
+     */
+    @TableId(value = "table_id")
+    private Long tableId;
+
+    /**
+     * 琛ㄥ悕绉�
+     */
+    @NotBlank(message = "琛ㄥ悕绉颁笉鑳戒负绌�")
+    private String tableName;
+
+    /**
+     * 琛ㄦ弿杩�
+     */
+    @NotBlank(message = "琛ㄦ弿杩颁笉鑳戒负绌�")
+    private String tableComment;
+
+    /**
+     * 鍏宠仈鐖惰〃鐨勮〃鍚�
+     */
+    private String subTableName;
+
+    /**
+     * 鏈〃鍏宠仈鐖惰〃鐨勫閿悕
+     */
+    private String subTableFkName;
+
+    /**
+     * 瀹炰綋绫诲悕绉�(棣栧瓧姣嶅ぇ鍐�)
+     */
+    @NotBlank(message = "瀹炰綋绫诲悕绉颁笉鑳戒负绌�")
+    private String className;
+
+    /**
+     * 浣跨敤鐨勬ā鏉匡紙crud鍗曡〃鎿嶄綔 tree鏍戣〃鎿嶄綔 sub涓诲瓙琛ㄦ搷浣滐級
+     */
+    private String tplCategory;
+
+    /**
+     * 鐢熸垚鍖呰矾寰�
+     */
+    @NotBlank(message = "鐢熸垚鍖呰矾寰勪笉鑳戒负绌�")
+    private String packageName;
+
+    /**
+     * 鐢熸垚妯″潡鍚�
+     */
+    @NotBlank(message = "鐢熸垚妯″潡鍚嶄笉鑳戒负绌�")
+    private String moduleName;
+
+    /**
+     * 鐢熸垚涓氬姟鍚�
+     */
+    @NotBlank(message = "鐢熸垚涓氬姟鍚嶄笉鑳戒负绌�")
+    private String businessName;
+
+    /**
+     * 鐢熸垚鍔熻兘鍚�
+     */
+    @NotBlank(message = "鐢熸垚鍔熻兘鍚嶄笉鑳戒负绌�")
+    private String functionName;
+
+    /**
+     * 鐢熸垚浣滆��
+     */
+    @NotBlank(message = "浣滆�呬笉鑳戒负绌�")
+    private String functionAuthor;
+
+    /**
+     * 鐢熸垚浠g爜鏂瑰紡锛�0zip鍘嬬缉鍖� 1鑷畾涔夎矾寰勶級
+     */
+    private String genType;
+
+    /**
+     * 鐢熸垚璺緞锛堜笉濉粯璁ら」鐩矾寰勶級
+     */
+    @TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+    private String genPath;
+
+    /**
+     * 涓婚敭淇℃伅
+     */
+    @TableField(exist = false)
+    private GenTableColumn pkColumn;
+
+    /**
+     * 琛ㄥ垪淇℃伅
+     */
+    @Valid
+    @TableField(exist = false)
+    private List<GenTableColumn> columns;
+
+    /**
+     * 鍏跺畠鐢熸垚閫夐」
+     */
+    private String options;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+    /**
+     * 鏍戠紪鐮佸瓧娈�
+     */
+    @TableField(exist = false)
+    private String treeCode;
+
+    /**
+     * 鏍戠埗缂栫爜瀛楁
+     */
+    @TableField(exist = false)
+    private String treeParentCode;
+
+    /**
+     * 鏍戝悕绉板瓧娈�
+     */
+    @TableField(exist = false)
+    private String treeName;
+
+    /*
+     * 鑿滃崟id鍒楄〃
+     */
+    @TableField(exist = false)
+    private List<Long> menuIds;
+
+    /**
+     * 涓婄骇鑿滃崟ID瀛楁
+     */
+    @TableField(exist = false)
+    private String parentMenuId;
+
+    /**
+     * 涓婄骇鑿滃崟鍚嶇О瀛楁
+     */
+    @TableField(exist = false)
+    private String parentMenuName;
+
+    public boolean isTree() {
+        return isTree(this.tplCategory);
+    }
+
+    public static boolean isTree(String tplCategory) {
+        return tplCategory != null && StringUtils.equals(GenConstants.TPL_TREE, tplCategory);
+    }
+
+    public boolean isCrud() {
+        return isCrud(this.tplCategory);
+    }
+
+    public static boolean isCrud(String tplCategory) {
+        return tplCategory != null && StringUtils.equals(GenConstants.TPL_CRUD, tplCategory);
+    }
+
+    public boolean isSuperColumn(String javaField) {
+        return isSuperColumn(this.tplCategory, javaField);
+    }
+
+    public static boolean isSuperColumn(String tplCategory, String javaField) {
+        return StringUtils.equalsAnyIgnoreCase(javaField, GenConstants.BASE_ENTITY);
+    }
+}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/domain/GenTableColumn.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/domain/GenTableColumn.java
new file mode 100644
index 0000000..5ce7ad0
--- /dev/null
+++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/domain/GenTableColumn.java
@@ -0,0 +1,223 @@
+package org.dromara.generator.domain;
+
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.apache.ibatis.type.JdbcType;
+
+import jakarta.validation.constraints.NotBlank;
+
+/**
+ * 浠g爜鐢熸垚涓氬姟瀛楁琛� gen_table_column
+ *
+ * @author Lion Li
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("gen_table_column")
+public class GenTableColumn extends BaseEntity {
+
+    /**
+     * 缂栧彿
+     */
+    @TableId(value = "column_id")
+    private Long columnId;
+
+    /**
+     * 褰掑睘琛ㄧ紪鍙�
+     */
+    private Long tableId;
+
+    /**
+     * 鍒楀悕绉�
+     */
+    private String columnName;
+
+    /**
+     * 鍒楁弿杩�
+     */
+    @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR)
+    private String columnComment;
+
+    /**
+     * 鍒楃被鍨�
+     */
+    private String columnType;
+
+    /**
+     * JAVA绫诲瀷
+     */
+    private String javaType;
+
+    /**
+     * JAVA瀛楁鍚�
+     */
+    @NotBlank(message = "Java灞炴�т笉鑳戒负绌�")
+    private String javaField;
+
+    /**
+     * 鏄惁涓婚敭锛�1鏄級
+     */
+    @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR)
+    private String isPk;
+
+    /**
+     * 鏄惁鑷锛�1鏄級
+     */
+    @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR)
+    private String isIncrement;
+
+    /**
+     * 鏄惁蹇呭~锛�1鏄級
+     */
+    @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR)
+    private String isRequired;
+
+    /**
+     * 鏄惁涓烘彃鍏ュ瓧娈碉紙1鏄級
+     */
+    @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR)
+    private String isInsert;
+
+    /**
+     * 鏄惁缂栬緫瀛楁锛�1鏄級
+     */
+    @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR)
+    private String isEdit;
+
+    /**
+     * 鏄惁鍒楄〃瀛楁锛�1鏄級
+     */
+    @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR)
+    private String isList;
+
+    /**
+     * 鏄惁鏌ヨ瀛楁锛�1鏄級
+     */
+    @TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR)
+    private String isQuery;
+
+    /**
+     * 鏌ヨ鏂瑰紡锛圗Q绛変簬銆丯E涓嶇瓑浜庛�丟T澶т簬銆丩T灏忎簬銆丩IKE妯$硦銆丅ETWEEN鑼冨洿锛�
+     */
+    private String queryType;
+
+    /**
+     * 鏄剧ず绫诲瀷锛坕nput鏂囨湰妗嗐�乼extarea鏂囨湰鍩熴�乻elect涓嬫媺妗嗐�乧heckbox澶嶉�夋銆乺adio鍗曢�夋銆乨atetime鏃ユ湡鎺т欢銆乮mage鍥剧墖涓婁紶鎺т欢銆乽pload鏂囦欢涓婁紶鎺т欢銆乪ditor瀵屾枃鏈帶浠讹級
+     */
+    private String htmlType;
+
+    /**
+     * 瀛楀吀绫诲瀷
+     */
+    private String dictType;
+
+    /**
+     * 鎺掑簭
+     */
+    private Integer sort;
+
+    public String getCapJavaField() {
+        return StringUtils.capitalize(javaField);
+    }
+
+    public boolean isPk() {
+        return isPk(this.isPk);
+    }
+
+    public boolean isPk(String isPk) {
+        return isPk != null && StringUtils.equals("1", isPk);
+    }
+
+    public boolean isIncrement() {
+        return isIncrement(this.isIncrement);
+    }
+
+    public boolean isIncrement(String isIncrement) {
+        return isIncrement != null && StringUtils.equals("1", isIncrement);
+    }
+
+    public boolean isRequired() {
+        return isRequired(this.isRequired);
+    }
+
+    public boolean isRequired(String isRequired) {
+        return isRequired != null && StringUtils.equals("1", isRequired);
+    }
+
+    public boolean isInsert() {
+        return isInsert(this.isInsert);
+    }
+
+    public boolean isInsert(String isInsert) {
+        return isInsert != null && StringUtils.equals("1", isInsert);
+    }
+
+    public boolean isEdit() {
+        return isInsert(this.isEdit);
+    }
+
+    public boolean isEdit(String isEdit) {
+        return isEdit != null && StringUtils.equals("1", isEdit);
+    }
+
+    public boolean isList() {
+        return isList(this.isList);
+    }
+
+    public boolean isList(String isList) {
+        return isList != null && StringUtils.equals("1", isList);
+    }
+
+    public boolean isQuery() {
+        return isQuery(this.isQuery);
+    }
+
+    public boolean isQuery(String isQuery) {
+        return isQuery != null && StringUtils.equals("1", isQuery);
+    }
+
+    public boolean isSuperColumn() {
+        return isSuperColumn(this.javaField);
+    }
+
+    public static boolean isSuperColumn(String javaField) {
+        return StringUtils.equalsAnyIgnoreCase(javaField,
+            // BaseEntity
+            "createBy", "createTime", "updateBy", "updateTime",
+            // TreeEntity
+            "parentName", "parentId");
+    }
+
+    public boolean isUsableColumn() {
+        return isUsableColumn(javaField);
+    }
+
+    public static boolean isUsableColumn(String javaField) {
+        // isSuperColumn()涓殑鍚嶅崟鐢ㄤ簬閬垮厤鐢熸垚澶氫綑Domain灞炴�э紝鑻ユ煇浜涘睘鎬у湪鐢熸垚椤甸潰鏃堕渶瑕佺敤鍒颁笉鑳藉拷鐣ワ紝鍒欐斁鍦ㄦ澶勭櫧鍚嶅崟
+        return StringUtils.equalsAnyIgnoreCase(javaField, "parentId", "orderNum", "remark");
+    }
+
+    public String readConverterExp() {
+        String remarks = StringUtils.substringBetween(this.columnComment, "锛�", "锛�");
+        StringBuffer sb = new StringBuffer();
+        if (StringUtils.isNotEmpty(remarks)) {
+            for (String value : remarks.split(" ")) {
+                if (StringUtils.isNotEmpty(value)) {
+                    Object startStr = value.subSequence(0, 1);
+                    String endStr = value.substring(1);
+                    sb.append(StringUtils.EMPTY).append(startStr).append("=").append(endStr).append(StringUtils.SEPARATOR);
+                }
+            }
+            return sb.deleteCharAt(sb.length() - 1).toString();
+        } else {
+            return this.columnComment;
+        }
+    }
+}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/mapper/GenTableColumnMapper.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/mapper/GenTableColumnMapper.java
new file mode 100644
index 0000000..3b5cb60
--- /dev/null
+++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/mapper/GenTableColumnMapper.java
@@ -0,0 +1,24 @@
+package org.dromara.generator.mapper;
+
+import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.generator.domain.GenTableColumn;
+
+import java.util.List;
+
+/**
+ * 涓氬姟瀛楁 鏁版嵁灞�
+ *
+ * @author Lion Li
+ */
+@InterceptorIgnore(dataPermission = "true", tenantLine = "true")
+public interface GenTableColumnMapper extends BaseMapperPlus<GenTableColumn, GenTableColumn> {
+    /**
+     * 鏍规嵁琛ㄥ悕绉版煡璇㈠垪淇℃伅
+     *
+     * @param tableName 琛ㄥ悕绉�
+     * @return 鍒椾俊鎭�
+     */
+    List<GenTableColumn> selectDbTableColumnsByName(String tableName);
+
+}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/mapper/GenTableMapper.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/mapper/GenTableMapper.java
new file mode 100644
index 0000000..30e33e8
--- /dev/null
+++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/mapper/GenTableMapper.java
@@ -0,0 +1,58 @@
+package org.dromara.generator.mapper;
+
+import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.generator.domain.GenTable;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 涓氬姟 鏁版嵁灞�
+ *
+ * @author Lion Li
+ */
+@InterceptorIgnore(dataPermission = "true", tenantLine = "true")
+public interface GenTableMapper extends BaseMapperPlus<GenTable, GenTable> {
+
+    /**
+     * 鏌ヨ鎹簱鍒楄〃
+     *
+     * @param genTable 鏌ヨ鏉′欢
+     * @return 鏁版嵁搴撹〃闆嗗悎
+     */
+    Page<GenTable> selectPageDbTableList(@Param("page") Page<GenTable> page, @Param("genTable") GenTable genTable);
+
+    /**
+     * 鏌ヨ鎹簱鍒楄〃
+     *
+     * @param tableNames 琛ㄥ悕绉扮粍
+     * @return 鏁版嵁搴撹〃闆嗗悎
+     */
+    List<GenTable> selectDbTableListByNames(String[] tableNames);
+
+    /**
+     * 鏌ヨ鎵�鏈夎〃淇℃伅
+     *
+     * @return 琛ㄤ俊鎭泦鍚�
+     */
+    List<GenTable> selectGenTableAll();
+
+    /**
+     * 鏌ヨ琛↖D涓氬姟淇℃伅
+     *
+     * @param id 涓氬姟ID
+     * @return 涓氬姟淇℃伅
+     */
+    GenTable selectGenTableById(Long id);
+
+    /**
+     * 鏌ヨ琛ㄥ悕绉颁笟鍔′俊鎭�
+     *
+     * @param tableName 琛ㄥ悕绉�
+     * @return 涓氬姟淇℃伅
+     */
+    GenTable selectGenTableByName(String tableName);
+
+}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/GenTableServiceImpl.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/GenTableServiceImpl.java
new file mode 100644
index 0000000..09ecb05
--- /dev/null
+++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/GenTableServiceImpl.java
@@ -0,0 +1,459 @@
+package org.dromara.generator.service;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.lang.Dict;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.dromara.common.core.constant.Constants;
+import org.dromara.generator.constant.GenConstants;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.StreamUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.core.utils.file.FileUtils;
+import org.dromara.common.json.utils.JsonUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.generator.domain.GenTable;
+import org.dromara.generator.domain.GenTableColumn;
+import org.dromara.generator.mapper.GenTableColumnMapper;
+import org.dromara.generator.mapper.GenTableMapper;
+import org.dromara.generator.util.GenUtils;
+import org.dromara.generator.util.VelocityInitializer;
+import org.dromara.generator.util.VelocityUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.Velocity;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+/**
+ * 涓氬姟 鏈嶅姟灞傚疄鐜�
+ *
+ * @author Lion Li
+ */
+@DS("#header.datasource")
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class GenTableServiceImpl implements IGenTableService {
+
+    private final GenTableMapper baseMapper;
+    private final GenTableColumnMapper genTableColumnMapper;
+    private final IdentifierGenerator identifierGenerator;
+
+    /**
+     * 鏌ヨ涓氬姟瀛楁鍒楄〃
+     *
+     * @param tableId 涓氬姟瀛楁缂栧彿
+     * @return 涓氬姟瀛楁闆嗗悎
+     */
+    @Override
+    public List<GenTableColumn> selectGenTableColumnListByTableId(Long tableId) {
+        return genTableColumnMapper.selectList(new LambdaQueryWrapper<GenTableColumn>()
+            .eq(GenTableColumn::getTableId, tableId)
+            .orderByAsc(GenTableColumn::getSort));
+    }
+
+    /**
+     * 鏌ヨ涓氬姟淇℃伅
+     *
+     * @param id 涓氬姟ID
+     * @return 涓氬姟淇℃伅
+     */
+    @Override
+    public GenTable selectGenTableById(Long id) {
+        GenTable genTable = baseMapper.selectGenTableById(id);
+        setTableFromOptions(genTable);
+        return genTable;
+    }
+
+    @Override
+    public TableDataInfo<GenTable> selectPageGenTableList(GenTable genTable, PageQuery pageQuery) {
+        Page<GenTable> page = baseMapper.selectPage(pageQuery.build(), this.buildGenTableQueryWrapper(genTable));
+        return TableDataInfo.build(page);
+    }
+
+    private QueryWrapper<GenTable> buildGenTableQueryWrapper(GenTable genTable) {
+        Map<String, Object> params = genTable.getParams();
+        QueryWrapper<GenTable> wrapper = Wrappers.query();
+        wrapper.like(StringUtils.isNotBlank(genTable.getTableName()), "lower(table_name)", StringUtils.lowerCase(genTable.getTableName()))
+            .like(StringUtils.isNotBlank(genTable.getTableComment()), "lower(table_comment)", StringUtils.lowerCase(genTable.getTableComment()))
+            .between(params.get("beginTime") != null && params.get("endTime") != null,
+                "create_time", params.get("beginTime"), params.get("endTime"));
+        return wrapper;
+    }
+
+
+    @Override
+    public TableDataInfo<GenTable> selectPageDbTableList(GenTable genTable, PageQuery pageQuery) {
+        Page<GenTable> page = baseMapper.selectPageDbTableList(pageQuery.build(), genTable);
+        return TableDataInfo.build(page);
+    }
+
+    /**
+     * 鏌ヨ鎹簱鍒楄〃
+     *
+     * @param tableNames 琛ㄥ悕绉扮粍
+     * @return 鏁版嵁搴撹〃闆嗗悎
+     */
+    @Override
+    public List<GenTable> selectDbTableListByNames(String[] tableNames) {
+        return baseMapper.selectDbTableListByNames(tableNames);
+    }
+
+    /**
+     * 鏌ヨ鎵�鏈夎〃淇℃伅
+     *
+     * @return 琛ㄤ俊鎭泦鍚�
+     */
+    @Override
+    public List<GenTable> selectGenTableAll() {
+        return baseMapper.selectGenTableAll();
+    }
+
+    /**
+     * 淇敼涓氬姟
+     *
+     * @param genTable 涓氬姟淇℃伅
+     * @return 缁撴灉
+     */
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void updateGenTable(GenTable genTable) {
+        String options = JsonUtils.toJsonString(genTable.getParams());
+        genTable.setOptions(options);
+        int row = baseMapper.updateById(genTable);
+        if (row > 0) {
+            for (GenTableColumn cenTableColumn : genTable.getColumns()) {
+                genTableColumnMapper.updateById(cenTableColumn);
+            }
+        }
+    }
+
+    /**
+     * 鍒犻櫎涓氬姟瀵硅薄
+     *
+     * @param tableIds 闇�瑕佸垹闄ょ殑鏁版嵁ID
+     * @return 缁撴灉
+     */
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void deleteGenTableByIds(Long[] tableIds) {
+        List<Long> ids = Arrays.asList(tableIds);
+        baseMapper.deleteBatchIds(ids);
+        genTableColumnMapper.delete(new LambdaQueryWrapper<GenTableColumn>().in(GenTableColumn::getTableId, ids));
+    }
+
+    /**
+     * 瀵煎叆琛ㄧ粨鏋�
+     *
+     * @param tableList 瀵煎叆琛ㄥ垪琛�
+     */
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void importGenTable(List<GenTable> tableList) {
+        String operName = LoginHelper.getUsername();
+        try {
+            for (GenTable table : tableList) {
+                String tableName = table.getTableName();
+                GenUtils.initTable(table, operName);
+                int row = baseMapper.insert(table);
+                if (row > 0) {
+                    // 淇濆瓨鍒椾俊鎭�
+                    List<GenTableColumn> genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName);
+                    List<GenTableColumn> saveColumns = new ArrayList<>();
+                    for (GenTableColumn column : genTableColumns) {
+                        GenUtils.initColumnField(column, table);
+                        saveColumns.add(column);
+                    }
+                    if (CollUtil.isNotEmpty(saveColumns)) {
+                        genTableColumnMapper.insertBatch(saveColumns);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            throw new ServiceException("瀵煎叆澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    /**
+     * 棰勮浠g爜
+     *
+     * @param tableId 琛ㄧ紪鍙�
+     * @return 棰勮鏁版嵁鍒楄〃
+     */
+    @Override
+    public Map<String, String> previewCode(Long tableId) {
+        Map<String, String> dataMap = new LinkedHashMap<>();
+        // 鏌ヨ琛ㄤ俊鎭�
+        GenTable table = baseMapper.selectGenTableById(tableId);
+        List<Long> menuIds = new ArrayList<>();
+        for (int i = 0; i < 6; i++) {
+            menuIds.add(identifierGenerator.nextId(null).longValue());
+        }
+        table.setMenuIds(menuIds);
+        // 璁剧疆涓婚敭鍒椾俊鎭�
+        setPkColumn(table);
+        VelocityInitializer.initVelocity();
+
+        VelocityContext context = VelocityUtils.prepareContext(table);
+
+        // 鑾峰彇妯℃澘鍒楄〃
+        List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
+        for (String template : templates) {
+            // 娓叉煋妯℃澘
+            StringWriter sw = new StringWriter();
+            Template tpl = Velocity.getTemplate(template, Constants.UTF8);
+            tpl.merge(context, sw);
+            dataMap.put(template, sw.toString());
+        }
+        return dataMap;
+    }
+
+    /**
+     * 鐢熸垚浠g爜锛堜笅杞芥柟寮忥級
+     *
+     * @param tableName 琛ㄥ悕绉�
+     * @return 鏁版嵁
+     */
+    @Override
+    public byte[] downloadCode(String tableName) {
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        ZipOutputStream zip = new ZipOutputStream(outputStream);
+        generatorCode(tableName, zip);
+        IoUtil.close(zip);
+        return outputStream.toByteArray();
+    }
+
+    /**
+     * 鐢熸垚浠g爜锛堣嚜瀹氫箟璺緞锛�
+     *
+     * @param tableName 琛ㄥ悕绉�
+     */
+    @Override
+    public void generatorCode(String tableName) {
+        // 鏌ヨ琛ㄤ俊鎭�
+        GenTable table = baseMapper.selectGenTableByName(tableName);
+        // 璁剧疆涓婚敭鍒椾俊鎭�
+        setPkColumn(table);
+
+        VelocityInitializer.initVelocity();
+
+        VelocityContext context = VelocityUtils.prepareContext(table);
+
+        // 鑾峰彇妯℃澘鍒楄〃
+        List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
+        for (String template : templates) {
+            if (!StringUtils.containsAny(template, "sql.vm", "api.js.vm", "index.vue.vm", "index-tree.vue.vm")) {
+                // 娓叉煋妯℃澘
+                StringWriter sw = new StringWriter();
+                Template tpl = Velocity.getTemplate(template, Constants.UTF8);
+                tpl.merge(context, sw);
+                try {
+                    String path = getGenPath(table, template);
+                    FileUtils.writeUtf8String(sw.toString(), path);
+                } catch (Exception e) {
+                    throw new ServiceException("娓叉煋妯℃澘澶辫触锛岃〃鍚嶏細" + table.getTableName());
+                }
+            }
+        }
+    }
+
+    /**
+     * 鍚屾鏁版嵁搴�
+     *
+     * @param tableName 琛ㄥ悕绉�
+     */
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void synchDb(String tableName) {
+        GenTable table = baseMapper.selectGenTableByName(tableName);
+        List<GenTableColumn> tableColumns = table.getColumns();
+        Map<String, GenTableColumn> tableColumnMap = StreamUtils.toIdentityMap(tableColumns, GenTableColumn::getColumnName);
+
+        List<GenTableColumn> dbTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName);
+        if (CollUtil.isEmpty(dbTableColumns)) {
+            throw new ServiceException("鍚屾鏁版嵁澶辫触锛屽師琛ㄧ粨鏋勪笉瀛樺湪");
+        }
+        List<String> dbTableColumnNames = StreamUtils.toList(dbTableColumns, GenTableColumn::getColumnName);
+
+        List<GenTableColumn> saveColumns = new ArrayList<>();
+        dbTableColumns.forEach(column -> {
+            GenUtils.initColumnField(column, table);
+            if (tableColumnMap.containsKey(column.getColumnName())) {
+                GenTableColumn prevColumn = tableColumnMap.get(column.getColumnName());
+                column.setColumnId(prevColumn.getColumnId());
+                if (column.isList()) {
+                    // 濡傛灉鏄垪琛紝缁х画淇濈暀鏌ヨ鏂瑰紡/瀛楀吀绫诲瀷閫夐」
+                    column.setDictType(prevColumn.getDictType());
+                    column.setQueryType(prevColumn.getQueryType());
+                }
+                if (StringUtils.isNotEmpty(prevColumn.getIsRequired()) && !column.isPk()
+                    && (column.isInsert() || column.isEdit())
+                    && ((column.isUsableColumn()) || (!column.isSuperColumn()))) {
+                    // 濡傛灉鏄�(鏂板/淇敼&闈炰富閿�/闈炲拷鐣ュ強鐖跺睘鎬�)锛岀户缁繚鐣欏繀濉�/鏄剧ず绫诲瀷閫夐」
+                    column.setIsRequired(prevColumn.getIsRequired());
+                    column.setHtmlType(prevColumn.getHtmlType());
+                }
+            }
+            saveColumns.add(column);
+        });
+        if (CollUtil.isNotEmpty(saveColumns)) {
+            genTableColumnMapper.insertOrUpdateBatch(saveColumns);
+        }
+        List<GenTableColumn> delColumns = StreamUtils.filter(tableColumns, column -> !dbTableColumnNames.contains(column.getColumnName()));
+        if (CollUtil.isNotEmpty(delColumns)) {
+            List<Long> ids = StreamUtils.toList(delColumns, GenTableColumn::getColumnId);
+            genTableColumnMapper.deleteBatchIds(ids);
+        }
+    }
+
+    /**
+     * 鎵归噺鐢熸垚浠g爜锛堜笅杞芥柟寮忥級
+     *
+     * @param tableNames 琛ㄦ暟缁�
+     * @return 鏁版嵁
+     */
+    @Override
+    public byte[] downloadCode(String[] tableNames) {
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        ZipOutputStream zip = new ZipOutputStream(outputStream);
+        for (String tableName : tableNames) {
+            generatorCode(tableName, zip);
+        }
+        IoUtil.close(zip);
+        return outputStream.toByteArray();
+    }
+
+    /**
+     * 鏌ヨ琛ㄤ俊鎭苟鐢熸垚浠g爜
+     */
+    private void generatorCode(String tableName, ZipOutputStream zip) {
+        // 鏌ヨ琛ㄤ俊鎭�
+        GenTable table = baseMapper.selectGenTableByName(tableName);
+        List<Long> menuIds = new ArrayList<>();
+        for (int i = 0; i < 6; i++) {
+            menuIds.add(identifierGenerator.nextId(null).longValue());
+        }
+        table.setMenuIds(menuIds);
+        // 璁剧疆涓婚敭鍒椾俊鎭�
+        setPkColumn(table);
+
+        VelocityInitializer.initVelocity();
+
+        VelocityContext context = VelocityUtils.prepareContext(table);
+
+        // 鑾峰彇妯℃澘鍒楄〃
+        List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
+        for (String template : templates) {
+            // 娓叉煋妯℃澘
+            StringWriter sw = new StringWriter();
+            Template tpl = Velocity.getTemplate(template, Constants.UTF8);
+            tpl.merge(context, sw);
+            try {
+                // 娣诲姞鍒皕ip
+                zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table)));
+                IoUtil.write(zip, StandardCharsets.UTF_8, false, sw.toString());
+                IoUtil.close(sw);
+                zip.flush();
+                zip.closeEntry();
+            } catch (IOException e) {
+                log.error("娓叉煋妯℃澘澶辫触锛岃〃鍚嶏細" + table.getTableName(), e);
+            }
+        }
+    }
+
+    /**
+     * 淇敼淇濆瓨鍙傛暟鏍¢獙
+     *
+     * @param genTable 涓氬姟淇℃伅
+     */
+    @Override
+    public void validateEdit(GenTable genTable) {
+        if (GenConstants.TPL_TREE.equals(genTable.getTplCategory())) {
+            String options = JsonUtils.toJsonString(genTable.getParams());
+            Dict paramsObj = JsonUtils.parseMap(options);
+            if (StringUtils.isEmpty(paramsObj.getStr(GenConstants.TREE_CODE))) {
+                throw new ServiceException("鏍戠紪鐮佸瓧娈典笉鑳戒负绌�");
+            } else if (StringUtils.isEmpty(paramsObj.getStr(GenConstants.TREE_PARENT_CODE))) {
+                throw new ServiceException("鏍戠埗缂栫爜瀛楁涓嶈兘涓虹┖");
+            } else if (StringUtils.isEmpty(paramsObj.getStr(GenConstants.TREE_NAME))) {
+                throw new ServiceException("鏍戝悕绉板瓧娈典笉鑳戒负绌�");
+            }
+        }
+    }
+
+    /**
+     * 璁剧疆涓婚敭鍒椾俊鎭�
+     *
+     * @param table 涓氬姟琛ㄤ俊鎭�
+     */
+    public void setPkColumn(GenTable table) {
+        for (GenTableColumn column : table.getColumns()) {
+            if (column.isPk()) {
+                table.setPkColumn(column);
+                break;
+            }
+        }
+        if (ObjectUtil.isNull(table.getPkColumn())) {
+            table.setPkColumn(table.getColumns().get(0));
+        }
+
+    }
+
+    /**
+     * 璁剧疆浠g爜鐢熸垚鍏朵粬閫夐」鍊�
+     *
+     * @param genTable 璁剧疆鍚庣殑鐢熸垚瀵硅薄
+     */
+    public void setTableFromOptions(GenTable genTable) {
+        Dict paramsObj = JsonUtils.parseMap(genTable.getOptions());
+        if (ObjectUtil.isNotNull(paramsObj)) {
+            String treeCode = paramsObj.getStr(GenConstants.TREE_CODE);
+            String treeParentCode = paramsObj.getStr(GenConstants.TREE_PARENT_CODE);
+            String treeName = paramsObj.getStr(GenConstants.TREE_NAME);
+            String parentMenuId = paramsObj.getStr(GenConstants.PARENT_MENU_ID);
+            String parentMenuName = paramsObj.getStr(GenConstants.PARENT_MENU_NAME);
+
+            genTable.setTreeCode(treeCode);
+            genTable.setTreeParentCode(treeParentCode);
+            genTable.setTreeName(treeName);
+            genTable.setParentMenuId(parentMenuId);
+            genTable.setParentMenuName(parentMenuName);
+        }
+    }
+
+    /**
+     * 鑾峰彇浠g爜鐢熸垚鍦板潃
+     *
+     * @param table    涓氬姟琛ㄤ俊鎭�
+     * @param template 妯℃澘鏂囦欢璺緞
+     * @return 鐢熸垚鍦板潃
+     */
+    public static String getGenPath(GenTable table, String template) {
+        String genPath = table.getGenPath();
+        if (StringUtils.equals(genPath, "/")) {
+            return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(template, table);
+        }
+        return genPath + File.separator + VelocityUtils.getFileName(template, table);
+    }
+}
+
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/IGenTableService.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/IGenTableService.java
new file mode 100644
index 0000000..643742b
--- /dev/null
+++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/IGenTableService.java
@@ -0,0 +1,133 @@
+package org.dromara.generator.service;
+
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.generator.domain.GenTable;
+import org.dromara.generator.domain.GenTableColumn;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 涓氬姟 鏈嶅姟灞�
+ *
+ * @author Lion Li
+ */
+public interface IGenTableService {
+
+    /**
+     * 鏌ヨ涓氬姟瀛楁鍒楄〃
+     *
+     * @param tableId 涓氬姟瀛楁缂栧彿
+     * @return 涓氬姟瀛楁闆嗗悎
+     */
+    List<GenTableColumn> selectGenTableColumnListByTableId(Long tableId);
+
+    /**
+     * 鏌ヨ涓氬姟鍒楄〃
+     *
+     * @param genTable 涓氬姟淇℃伅
+     * @return 涓氬姟闆嗗悎
+     */
+    TableDataInfo<GenTable> selectPageGenTableList(GenTable genTable, PageQuery pageQuery);
+
+    /**
+     * 鏌ヨ鎹簱鍒楄〃
+     *
+     * @param genTable 涓氬姟淇℃伅
+     * @return 鏁版嵁搴撹〃闆嗗悎
+     */
+    TableDataInfo<GenTable> selectPageDbTableList(GenTable genTable, PageQuery pageQuery);
+
+    /**
+     * 鏌ヨ鎹簱鍒楄〃
+     *
+     * @param tableNames 琛ㄥ悕绉扮粍
+     * @return 鏁版嵁搴撹〃闆嗗悎
+     */
+    List<GenTable> selectDbTableListByNames(String[] tableNames);
+
+    /**
+     * 鏌ヨ鎵�鏈夎〃淇℃伅
+     *
+     * @return 琛ㄤ俊鎭泦鍚�
+     */
+    List<GenTable> selectGenTableAll();
+
+    /**
+     * 鏌ヨ涓氬姟淇℃伅
+     *
+     * @param id 涓氬姟ID
+     * @return 涓氬姟淇℃伅
+     */
+    GenTable selectGenTableById(Long id);
+
+    /**
+     * 淇敼涓氬姟
+     *
+     * @param genTable 涓氬姟淇℃伅
+     * @return 缁撴灉
+     */
+    void updateGenTable(GenTable genTable);
+
+    /**
+     * 鍒犻櫎涓氬姟淇℃伅
+     *
+     * @param tableIds 闇�瑕佸垹闄ょ殑琛ㄦ暟鎹甀D
+     * @return 缁撴灉
+     */
+    void deleteGenTableByIds(Long[] tableIds);
+
+    /**
+     * 瀵煎叆琛ㄧ粨鏋�
+     *
+     * @param tableList 瀵煎叆琛ㄥ垪琛�
+     */
+    void importGenTable(List<GenTable> tableList);
+
+    /**
+     * 棰勮浠g爜
+     *
+     * @param tableId 琛ㄧ紪鍙�
+     * @return 棰勮鏁版嵁鍒楄〃
+     */
+    Map<String, String> previewCode(Long tableId);
+
+    /**
+     * 鐢熸垚浠g爜锛堜笅杞芥柟寮忥級
+     *
+     * @param tableName 琛ㄥ悕绉�
+     * @return 鏁版嵁
+     */
+    byte[] downloadCode(String tableName);
+
+    /**
+     * 鐢熸垚浠g爜锛堣嚜瀹氫箟璺緞锛�
+     *
+     * @param tableName 琛ㄥ悕绉�
+     * @return 鏁版嵁
+     */
+    void generatorCode(String tableName);
+
+    /**
+     * 鍚屾鏁版嵁搴�
+     *
+     * @param tableName 琛ㄥ悕绉�
+     */
+    void synchDb(String tableName);
+
+    /**
+     * 鎵归噺鐢熸垚浠g爜锛堜笅杞芥柟寮忥級
+     *
+     * @param tableNames 琛ㄦ暟缁�
+     * @return 鏁版嵁
+     */
+    byte[] downloadCode(String[] tableNames);
+
+    /**
+     * 淇敼淇濆瓨鍙傛暟鏍¢獙
+     *
+     * @param genTable 涓氬姟淇℃伅
+     */
+    void validateEdit(GenTable genTable);
+}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/util/GenUtils.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/util/GenUtils.java
new file mode 100644
index 0000000..948a930
--- /dev/null
+++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/util/GenUtils.java
@@ -0,0 +1,233 @@
+package org.dromara.generator.util;
+
+import org.dromara.generator.constant.GenConstants;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.generator.config.GenConfig;
+import org.dromara.generator.domain.GenTable;
+import org.dromara.generator.domain.GenTableColumn;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.RegExUtils;
+
+import java.util.Arrays;
+
+/**
+ * 浠g爜鐢熸垚鍣� 宸ュ叿绫�
+ *
+ * @author ruoyi
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class GenUtils {
+
+    /**
+     * 鍒濆鍖栬〃淇℃伅
+     */
+    public static void initTable(GenTable genTable, String operName) {
+        genTable.setClassName(convertClassName(genTable.getTableName()));
+        genTable.setPackageName(GenConfig.getPackageName());
+        genTable.setModuleName(getModuleName(GenConfig.getPackageName()));
+        genTable.setBusinessName(getBusinessName(genTable.getTableName()));
+        genTable.setFunctionName(replaceText(genTable.getTableComment()));
+        genTable.setFunctionAuthor(GenConfig.getAuthor());
+        genTable.setCreateBy(LoginHelper.getUserId());
+    }
+
+    /**
+     * 鍒濆鍖栧垪灞炴�у瓧娈�
+     */
+    public static void initColumnField(GenTableColumn column, GenTable table) {
+        String dataType = getDbType(column.getColumnType());
+        String columnName = column.getColumnName();
+        column.setTableId(table.getTableId());
+        column.setCreateBy(table.getCreateBy());
+        // 璁剧疆java瀛楁鍚�
+        column.setJavaField(StringUtils.toCamelCase(columnName));
+        // 璁剧疆榛樿绫诲瀷
+        column.setJavaType(GenConstants.TYPE_STRING);
+        column.setQueryType(GenConstants.QUERY_EQ);
+
+        if (arraysContains(GenConstants.COLUMNTYPE_STR, dataType) || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType)) {
+            // 瀛楃涓查暱搴﹁秴杩�500璁剧疆涓烘枃鏈煙
+            Integer columnLength = getColumnLength(column.getColumnType());
+            String htmlType = columnLength >= 500 || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType) ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT;
+            column.setHtmlType(htmlType);
+        } else if (arraysContains(GenConstants.COLUMNTYPE_TIME, dataType)) {
+            column.setJavaType(GenConstants.TYPE_DATE);
+            column.setHtmlType(GenConstants.HTML_DATETIME);
+        } else if (arraysContains(GenConstants.COLUMNTYPE_NUMBER, dataType)) {
+            column.setHtmlType(GenConstants.HTML_INPUT);
+
+            // 濡傛灉鏄诞鐐瑰瀷 缁熶竴鐢˙igDecimal
+            String[] str = StringUtils.split(StringUtils.substringBetween(column.getColumnType(), "(", ")"), StringUtils.SEPARATOR);
+            if (str != null && str.length == 2 && Integer.parseInt(str[1]) > 0) {
+                column.setJavaType(GenConstants.TYPE_BIGDECIMAL);
+            }
+            // 濡傛灉鏄暣褰�
+            else if (str != null && str.length == 1 && Integer.parseInt(str[0]) <= 10) {
+                column.setJavaType(GenConstants.TYPE_INTEGER);
+            }
+            // 闀挎暣褰�
+            else {
+                column.setJavaType(GenConstants.TYPE_LONG);
+            }
+        }
+
+        // BO瀵硅薄 榛樿鎻掑叆鍕鹃��
+        if (!arraysContains(GenConstants.COLUMNNAME_NOT_ADD, columnName) && !column.isPk()) {
+            column.setIsInsert(GenConstants.REQUIRE);
+        }
+        // BO瀵硅薄 榛樿缂栬緫鍕鹃��
+        if (!arraysContains(GenConstants.COLUMNNAME_NOT_EDIT, columnName)) {
+            column.setIsEdit(GenConstants.REQUIRE);
+        }
+        // BO瀵硅薄 榛樿鏄惁蹇呭~鍕鹃��
+        if (!arraysContains(GenConstants.COLUMNNAME_NOT_EDIT, columnName)) {
+            column.setIsRequired(GenConstants.REQUIRE);
+        }
+        // VO瀵硅薄 榛樿杩斿洖鍕鹃��
+        if (!arraysContains(GenConstants.COLUMNNAME_NOT_LIST, columnName)) {
+            column.setIsList(GenConstants.REQUIRE);
+        }
+        // BO瀵硅薄 榛樿鏌ヨ鍕鹃��
+        if (!arraysContains(GenConstants.COLUMNNAME_NOT_QUERY, columnName) && !column.isPk()) {
+            column.setIsQuery(GenConstants.REQUIRE);
+        }
+
+        // 鏌ヨ瀛楁绫诲瀷
+        if (StringUtils.endsWithIgnoreCase(columnName, "name")) {
+            column.setQueryType(GenConstants.QUERY_LIKE);
+        }
+        // 鐘舵�佸瓧娈佃缃崟閫夋
+        if (StringUtils.endsWithIgnoreCase(columnName, "status")) {
+            column.setHtmlType(GenConstants.HTML_RADIO);
+        }
+        // 绫诲瀷&鎬у埆瀛楁璁剧疆涓嬫媺妗�
+        else if (StringUtils.endsWithIgnoreCase(columnName, "type")
+            || StringUtils.endsWithIgnoreCase(columnName, "sex")) {
+            column.setHtmlType(GenConstants.HTML_SELECT);
+        }
+        // 鍥剧墖瀛楁璁剧疆鍥剧墖涓婁紶鎺т欢
+        else if (StringUtils.endsWithIgnoreCase(columnName, "image")) {
+            column.setHtmlType(GenConstants.HTML_IMAGE_UPLOAD);
+        }
+        // 鏂囦欢瀛楁璁剧疆鏂囦欢涓婁紶鎺т欢
+        else if (StringUtils.endsWithIgnoreCase(columnName, "file")) {
+            column.setHtmlType(GenConstants.HTML_FILE_UPLOAD);
+        }
+        // 鍐呭瀛楁璁剧疆瀵屾枃鏈帶浠�
+        else if (StringUtils.endsWithIgnoreCase(columnName, "content")) {
+            column.setHtmlType(GenConstants.HTML_EDITOR);
+        }
+    }
+
+    /**
+     * 鏍¢獙鏁扮粍鏄惁鍖呭惈鎸囧畾鍊�
+     *
+     * @param arr         鏁扮粍
+     * @param targetValue 鍊�
+     * @return 鏄惁鍖呭惈
+     */
+    public static boolean arraysContains(String[] arr, String targetValue) {
+        return Arrays.asList(arr).contains(targetValue);
+    }
+
+    /**
+     * 鑾峰彇妯″潡鍚�
+     *
+     * @param packageName 鍖呭悕
+     * @return 妯″潡鍚�
+     */
+    public static String getModuleName(String packageName) {
+        int lastIndex = packageName.lastIndexOf(".");
+        int nameLength = packageName.length();
+        return StringUtils.substring(packageName, lastIndex + 1, nameLength);
+    }
+
+    /**
+     * 鑾峰彇涓氬姟鍚�
+     *
+     * @param tableName 琛ㄥ悕
+     * @return 涓氬姟鍚�
+     */
+    public static String getBusinessName(String tableName) {
+        int firstIndex = tableName.indexOf("_");
+        int nameLength = tableName.length();
+        String businessName = StringUtils.substring(tableName, firstIndex + 1, nameLength);
+        businessName = StringUtils.toCamelCase(businessName);
+        return businessName;
+    }
+
+    /**
+     * 琛ㄥ悕杞崲鎴怞ava绫诲悕
+     *
+     * @param tableName 琛ㄥ悕绉�
+     * @return 绫诲悕
+     */
+    public static String convertClassName(String tableName) {
+        boolean autoRemovePre = GenConfig.getAutoRemovePre();
+        String tablePrefix = GenConfig.getTablePrefix();
+        if (autoRemovePre && StringUtils.isNotEmpty(tablePrefix)) {
+            String[] searchList = StringUtils.split(tablePrefix, StringUtils.SEPARATOR);
+            tableName = replaceFirst(tableName, searchList);
+        }
+        return StringUtils.convertToCamelCase(tableName);
+    }
+
+    /**
+     * 鎵归噺鏇挎崲鍓嶇紑
+     *
+     * @param replacementm 鏇挎崲鍊�
+     * @param searchList   鏇挎崲鍒楄〃
+     * @return
+     */
+    public static String replaceFirst(String replacementm, String[] searchList) {
+        String text = replacementm;
+        for (String searchString : searchList) {
+            if (replacementm.startsWith(searchString)) {
+                text = replacementm.replaceFirst(searchString, "");
+                break;
+            }
+        }
+        return text;
+    }
+
+    /**
+     * 鍏抽敭瀛楁浛鎹�
+     *
+     * @param text 闇�瑕佽鏇挎崲鐨勫悕瀛�
+     * @return 鏇挎崲鍚庣殑鍚嶅瓧
+     */
+    public static String replaceText(String text) {
+        return RegExUtils.replaceAll(text, "(?:琛▅鑻ヤ緷)", "");
+    }
+
+    /**
+     * 鑾峰彇鏁版嵁搴撶被鍨嬪瓧娈�
+     *
+     * @param columnType 鍒楃被鍨�
+     * @return 鎴彇鍚庣殑鍒楃被鍨�
+     */
+    public static String getDbType(String columnType) {
+        if (StringUtils.indexOf(columnType, '(') > 0) {
+            return StringUtils.substringBefore(columnType, "(");
+        } else {
+            return columnType;
+        }
+    }
+
+    /**
+     * 鑾峰彇瀛楁闀垮害
+     *
+     * @param columnType 鍒楃被鍨�
+     * @return 鎴彇鍚庣殑鍒楃被鍨�
+     */
+    public static Integer getColumnLength(String columnType) {
+        if (StringUtils.indexOf(columnType, '(') > 0) {
+            String length = StringUtils.substringBetween(columnType, "(", ")");
+            return Integer.valueOf(length);
+        } else {
+            return 0;
+        }
+    }
+}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/util/VelocityInitializer.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/util/VelocityInitializer.java
new file mode 100644
index 0000000..09e0121
--- /dev/null
+++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/util/VelocityInitializer.java
@@ -0,0 +1,35 @@
+package org.dromara.generator.util;
+
+import org.dromara.common.core.constant.Constants;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.apache.velocity.app.Velocity;
+
+import java.util.Properties;
+
+/**
+ * VelocityEngine宸ュ巶
+ *
+ * @author ruoyi
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class VelocityInitializer {
+
+    /**
+     * 鍒濆鍖杤m鏂规硶
+     */
+    public static void initVelocity() {
+        Properties p = new Properties();
+        try {
+            // 鍔犺浇classpath鐩綍涓嬬殑vm鏂囦欢
+            p.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
+            // 瀹氫箟瀛楃闆�
+            p.setProperty(Velocity.INPUT_ENCODING, Constants.UTF8);
+            // 鍒濆鍖朧elocity寮曟搸锛屾寚瀹氶厤缃甈roperties
+            Velocity.init(p);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/util/VelocityUtils.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/util/VelocityUtils.java
new file mode 100644
index 0000000..58219c9
--- /dev/null
+++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/util/VelocityUtils.java
@@ -0,0 +1,335 @@
+package org.dromara.generator.util;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.lang.Dict;
+import org.dromara.generator.constant.GenConstants;
+import org.dromara.common.core.utils.DateUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.json.utils.JsonUtils;
+import org.dromara.common.mybatis.helper.DataBaseHelper;
+import org.dromara.generator.domain.GenTable;
+import org.dromara.generator.domain.GenTableColumn;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.apache.velocity.VelocityContext;
+
+import java.util.*;
+
+/**
+ * 妯℃澘澶勭悊宸ュ叿绫�
+ *
+ * @author ruoyi
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class VelocityUtils {
+
+    /**
+     * 椤圭洰绌洪棿璺緞
+     */
+    private static final String PROJECT_PATH = "main/java";
+
+    /**
+     * mybatis绌洪棿璺緞
+     */
+    private static final String MYBATIS_PATH = "main/resources/mapper";
+
+    /**
+     * 榛樿涓婄骇鑿滃崟锛岀郴缁熷伐鍏�
+     */
+    private static final String DEFAULT_PARENT_MENU_ID = "3";
+
+    /**
+     * 璁剧疆妯℃澘鍙橀噺淇℃伅
+     *
+     * @return 妯℃澘鍒楄〃
+     */
+    public static VelocityContext prepareContext(GenTable genTable) {
+        String moduleName = genTable.getModuleName();
+        String businessName = genTable.getBusinessName();
+        String packageName = genTable.getPackageName();
+        String tplCategory = genTable.getTplCategory();
+        String functionName = genTable.getFunctionName();
+
+        VelocityContext velocityContext = new VelocityContext();
+        velocityContext.put("tplCategory", genTable.getTplCategory());
+        velocityContext.put("tableName", genTable.getTableName());
+        velocityContext.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "銆愯濉啓鍔熻兘鍚嶇О銆�");
+        velocityContext.put("ClassName", genTable.getClassName());
+        velocityContext.put("className", StringUtils.uncapitalize(genTable.getClassName()));
+        velocityContext.put("moduleName", genTable.getModuleName());
+        velocityContext.put("BusinessName", StringUtils.capitalize(genTable.getBusinessName()));
+        velocityContext.put("businessName", genTable.getBusinessName());
+        velocityContext.put("basePackage", getPackagePrefix(packageName));
+        velocityContext.put("packageName", packageName);
+        velocityContext.put("author", genTable.getFunctionAuthor());
+        velocityContext.put("datetime", DateUtils.getDate());
+        velocityContext.put("pkColumn", genTable.getPkColumn());
+        velocityContext.put("importList", getImportList(genTable));
+        velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName));
+        velocityContext.put("columns", genTable.getColumns());
+        velocityContext.put("table", genTable);
+        velocityContext.put("dicts", getDicts(genTable));
+        setMenuVelocityContext(velocityContext, genTable);
+        if (GenConstants.TPL_TREE.equals(tplCategory)) {
+            setTreeVelocityContext(velocityContext, genTable);
+        }
+        return velocityContext;
+    }
+
+    public static void setMenuVelocityContext(VelocityContext context, GenTable genTable) {
+        String options = genTable.getOptions();
+        Dict paramsObj = JsonUtils.parseMap(options);
+        String parentMenuId = getParentMenuId(paramsObj);
+        context.put("parentMenuId", parentMenuId);
+    }
+
+    public static void setTreeVelocityContext(VelocityContext context, GenTable genTable) {
+        String options = genTable.getOptions();
+        Dict paramsObj = JsonUtils.parseMap(options);
+        String treeCode = getTreecode(paramsObj);
+        String treeParentCode = getTreeParentCode(paramsObj);
+        String treeName = getTreeName(paramsObj);
+
+        context.put("treeCode", treeCode);
+        context.put("treeParentCode", treeParentCode);
+        context.put("treeName", treeName);
+        context.put("expandColumn", getExpandColumn(genTable));
+        if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) {
+            context.put("tree_parent_code", paramsObj.get(GenConstants.TREE_PARENT_CODE));
+        }
+        if (paramsObj.containsKey(GenConstants.TREE_NAME)) {
+            context.put("tree_name", paramsObj.get(GenConstants.TREE_NAME));
+        }
+    }
+
+    /**
+     * 鑾峰彇妯℃澘淇℃伅
+     *
+     * @return 妯℃澘鍒楄〃
+     */
+    public static List<String> getTemplateList(String tplCategory) {
+        List<String> templates = new ArrayList<String>();
+        templates.add("vm/java/domain.java.vm");
+        templates.add("vm/java/vo.java.vm");
+        templates.add("vm/java/bo.java.vm");
+        templates.add("vm/java/mapper.java.vm");
+        templates.add("vm/java/service.java.vm");
+        templates.add("vm/java/serviceImpl.java.vm");
+        templates.add("vm/java/controller.java.vm");
+        templates.add("vm/xml/mapper.xml.vm");
+        if (DataBaseHelper.isOracle()) {
+            templates.add("vm/sql/oracle/sql.vm");
+        } else if (DataBaseHelper.isPostgerSql()) {
+            templates.add("vm/sql/postgres/sql.vm");
+        } else if (DataBaseHelper.isSqlServer()) {
+            templates.add("vm/sql/sqlserver/sql.vm");
+        } else {
+            templates.add("vm/sql/sql.vm");
+        }
+        templates.add("vm/js/api.js.vm");
+        if (GenConstants.TPL_CRUD.equals(tplCategory)) {
+            templates.add("vm/vue/index.vue.vm");
+        } else if (GenConstants.TPL_TREE.equals(tplCategory)) {
+            templates.add("vm/vue/index-tree.vue.vm");
+        }
+        return templates;
+    }
+
+    /**
+     * 鑾峰彇鏂囦欢鍚�
+     */
+    public static String getFileName(String template, GenTable genTable) {
+        // 鏂囦欢鍚嶇О
+        String fileName = "";
+        // 鍖呰矾寰�
+        String packageName = genTable.getPackageName();
+        // 妯″潡鍚�
+        String moduleName = genTable.getModuleName();
+        // 澶у啓绫诲悕
+        String className = genTable.getClassName();
+        // 涓氬姟鍚嶇О
+        String businessName = genTable.getBusinessName();
+
+        String javaPath = PROJECT_PATH + "/" + StringUtils.replace(packageName, ".", "/");
+        String mybatisPath = MYBATIS_PATH + "/" + moduleName;
+        String vuePath = "vue";
+
+        if (template.contains("domain.java.vm")) {
+            fileName = StringUtils.format("{}/domain/{}.java", javaPath, className);
+        }
+        if (template.contains("vo.java.vm")) {
+            fileName = StringUtils.format("{}/domain/vo/{}Vo.java", javaPath, className);
+        }
+        if (template.contains("bo.java.vm")) {
+            fileName = StringUtils.format("{}/domain/bo/{}Bo.java", javaPath, className);
+        }
+        if (template.contains("mapper.java.vm")) {
+            fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className);
+        } else if (template.contains("service.java.vm")) {
+            fileName = StringUtils.format("{}/service/I{}Service.java", javaPath, className);
+        } else if (template.contains("serviceImpl.java.vm")) {
+            fileName = StringUtils.format("{}/service/impl/{}ServiceImpl.java", javaPath, className);
+        } else if (template.contains("controller.java.vm")) {
+            fileName = StringUtils.format("{}/controller/{}Controller.java", javaPath, className);
+        } else if (template.contains("mapper.xml.vm")) {
+            fileName = StringUtils.format("{}/{}Mapper.xml", mybatisPath, className);
+        } else if (template.contains("sql.vm")) {
+            fileName = businessName + "Menu.sql";
+        } else if (template.contains("api.js.vm")) {
+            fileName = StringUtils.format("{}/api/{}/{}.js", vuePath, moduleName, businessName);
+        } else if (template.contains("index.vue.vm")) {
+            fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName);
+        } else if (template.contains("index-tree.vue.vm")) {
+            fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName);
+        }
+        return fileName;
+    }
+
+    /**
+     * 鑾峰彇鍖呭墠缂�
+     *
+     * @param packageName 鍖呭悕绉�
+     * @return 鍖呭墠缂�鍚嶇О
+     */
+    public static String getPackagePrefix(String packageName) {
+        int lastIndex = packageName.lastIndexOf(".");
+        return StringUtils.substring(packageName, 0, lastIndex);
+    }
+
+    /**
+     * 鏍规嵁鍒楃被鍨嬭幏鍙栧鍏ュ寘
+     *
+     * @param genTable 涓氬姟琛ㄥ璞�
+     * @return 杩斿洖闇�瑕佸鍏ョ殑鍖呭垪琛�
+     */
+    public static HashSet<String> getImportList(GenTable genTable) {
+        List<GenTableColumn> columns = genTable.getColumns();
+        HashSet<String> importList = new HashSet<String>();
+        for (GenTableColumn column : columns) {
+            if (!column.isSuperColumn() && GenConstants.TYPE_DATE.equals(column.getJavaType())) {
+                importList.add("java.util.Date");
+                importList.add("com.fasterxml.jackson.annotation.JsonFormat");
+            } else if (!column.isSuperColumn() && GenConstants.TYPE_BIGDECIMAL.equals(column.getJavaType())) {
+                importList.add("java.math.BigDecimal");
+            }
+        }
+        return importList;
+    }
+
+    /**
+     * 鏍规嵁鍒楃被鍨嬭幏鍙栧瓧鍏哥粍
+     *
+     * @param genTable 涓氬姟琛ㄥ璞�
+     * @return 杩斿洖瀛楀吀缁�
+     */
+    public static String getDicts(GenTable genTable) {
+        List<GenTableColumn> columns = genTable.getColumns();
+        Set<String> dicts = new HashSet<>();
+        addDicts(dicts, columns);
+        return StringUtils.join(dicts, ", ");
+    }
+
+    /**
+     * 娣诲姞瀛楀吀鍒楄〃
+     *
+     * @param dicts 瀛楀吀鍒楄〃
+     * @param columns 鍒楅泦鍚�
+     */
+    public static void addDicts(Set<String> dicts, List<GenTableColumn> columns) {
+        for (GenTableColumn column : columns) {
+            if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny(
+                column.getHtmlType(),
+                new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX })) {
+                dicts.add("'" + column.getDictType() + "'");
+            }
+        }
+    }
+
+    /**
+     * 鑾峰彇鏉冮檺鍓嶇紑
+     *
+     * @param moduleName   妯″潡鍚嶇О
+     * @param businessName 涓氬姟鍚嶇О
+     * @return 杩斿洖鏉冮檺鍓嶇紑
+     */
+    public static String getPermissionPrefix(String moduleName, String businessName) {
+        return StringUtils.format("{}:{}", moduleName, businessName);
+    }
+
+    /**
+     * 鑾峰彇涓婄骇鑿滃崟ID瀛楁
+     *
+     * @param paramsObj 鐢熸垚鍏朵粬閫夐」
+     * @return 涓婄骇鑿滃崟ID瀛楁
+     */
+    public static String getParentMenuId(Dict paramsObj) {
+        if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.PARENT_MENU_ID)
+            && StringUtils.isNotEmpty(paramsObj.getStr(GenConstants.PARENT_MENU_ID))) {
+            return paramsObj.getStr(GenConstants.PARENT_MENU_ID);
+        }
+        return DEFAULT_PARENT_MENU_ID;
+    }
+
+    /**
+     * 鑾峰彇鏍戠紪鐮�
+     *
+     * @param paramsObj 鐢熸垚鍏朵粬閫夐」
+     * @return 鏍戠紪鐮�
+     */
+    public static String getTreecode(Map<String, Object> paramsObj) {
+        if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_CODE)) {
+            return StringUtils.toCamelCase(Convert.toStr(paramsObj.get(GenConstants.TREE_CODE)));
+        }
+        return StringUtils.EMPTY;
+    }
+
+    /**
+     * 鑾峰彇鏍戠埗缂栫爜
+     *
+     * @param paramsObj 鐢熸垚鍏朵粬閫夐」
+     * @return 鏍戠埗缂栫爜
+     */
+    public static String getTreeParentCode(Dict paramsObj) {
+        if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) {
+            return StringUtils.toCamelCase(paramsObj.getStr(GenConstants.TREE_PARENT_CODE));
+        }
+        return StringUtils.EMPTY;
+    }
+
+    /**
+     * 鑾峰彇鏍戝悕绉�
+     *
+     * @param paramsObj 鐢熸垚鍏朵粬閫夐」
+     * @return 鏍戝悕绉�
+     */
+    public static String getTreeName(Dict paramsObj) {
+        if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_NAME)) {
+            return StringUtils.toCamelCase(paramsObj.getStr(GenConstants.TREE_NAME));
+        }
+        return StringUtils.EMPTY;
+    }
+
+    /**
+     * 鑾峰彇闇�瑕佸湪鍝竴鍒椾笂闈㈡樉绀哄睍寮�鎸夐挳
+     *
+     * @param genTable 涓氬姟琛ㄥ璞�
+     * @return 灞曞紑鎸夐挳鍒楀簭鍙�
+     */
+    public static int getExpandColumn(GenTable genTable) {
+        String options = genTable.getOptions();
+        Dict paramsObj = JsonUtils.parseMap(options);
+        String treeName = paramsObj.getStr(GenConstants.TREE_NAME);
+        int num = 0;
+        for (GenTableColumn column : genTable.getColumns()) {
+            if (column.isList()) {
+                num++;
+                String columnName = column.getColumnName();
+                if (columnName.equals(treeName)) {
+                    break;
+                }
+            }
+        }
+        return num;
+    }
+}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/generator.yml b/ruoyi-modules/ruoyi-generator/src/main/resources/generator.yml
index 5bd3dd6..d779d97 100644
--- a/ruoyi-modules/ruoyi-generator/src/main/resources/generator.yml
+++ b/ruoyi-modules/ruoyi-generator/src/main/resources/generator.yml
@@ -1,10 +1,10 @@
 # 浠g爜鐢熸垚
-gen: 
+gen:
   # 浣滆��
-  author: ruoyi
+  author: Lion Li
   # 榛樿鐢熸垚鍖呰矾寰� system 闇�鏀规垚鑷繁鐨勬ā鍧楀悕绉� 濡� system monitor tool
-  packageName: com.ruoyi.system
+  packageName: org.dromara.system
   # 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸false
   autoRemovePre: false
   # 琛ㄥ墠缂�锛堢敓鎴愮被鍚嶄笉浼氬寘鍚〃鍓嶇紑锛屽涓敤閫楀彿鍒嗛殧锛�
-  tablePrefix: sys_
\ No newline at end of file
+  tablePrefix: sys_
diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml b/ruoyi-modules/ruoyi-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml
index 24a26b1..4023f0e 100644
--- a/ruoyi-modules/ruoyi-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml
+++ b/ruoyi-modules/ruoyi-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml
@@ -2,13 +2,13 @@
 <!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.generator.mapper.GenTableColumnMapper">
+<mapper namespace="org.dromara.generator.mapper.GenTableColumnMapper">
 
-    <resultMap type="com.ruoyi.generator.domain.GenTableColumn" id="GenTableColumnResult">
+    <resultMap type="org.dromara.generator.domain.GenTableColumn" id="GenTableColumnResult">
     </resultMap>
 
     <select id="selectDbTableColumnsByName" parameterType="String" resultMap="GenTableColumnResult">
-        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isMySql()">
+        <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isMySql()">
             select column_name,
                    (case when (is_nullable = 'no' <![CDATA[ && ]]> column_key != 'PRI') then '1' else null end) as is_required,
                    (case when column_key = 'PRI' then '1' else '0' end) as is_pk,
@@ -19,7 +19,7 @@
             from information_schema.columns where table_schema = (select database()) and table_name = (#{tableName})
             order by ordinal_position
         </if>
-        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isOracle()">
+        <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isOracle()">
             select lower(temp.column_name) as column_name,
                     (case when (temp.nullable = 'N'  and  temp.constraint_type != 'P') then '1' else null end) as is_required,
                     (case when temp.constraint_type = 'P' then '1' else '0' end) as is_pk,
@@ -39,7 +39,7 @@
             WHERE temp.row_flg = 1
             ORDER BY temp.column_id
         </if>
-        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isPostgerSql()">
+        <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isPostgerSql()">
             SELECT column_name, is_required, is_pk, sort, column_comment, is_increment, column_type
             FROM (
                 SELECT c.relname AS table_name,
@@ -73,7 +73,7 @@
             WHERE table_name = (#{tableName})
                 AND column_type <![CDATA[ <> ]]> '-'
         </if>
-        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isSqlServer()">
+        <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isSqlServer()">
             SELECT
                 cast(A.NAME as nvarchar) as column_name,
                 cast(B.NAME as nvarchar) + (case when B.NAME = 'numeric' then '(' + cast(A.prec as nvarchar) + ',' + cast(A.scale as nvarchar) + ')' else '' end) as column_type,
diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml b/ruoyi-modules/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml
index f23b000..1ae784f 100644
--- a/ruoyi-modules/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml
+++ b/ruoyi-modules/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml
@@ -2,20 +2,20 @@
 <!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.generator.mapper.GenTableMapper">
+<mapper namespace="org.dromara.generator.mapper.GenTableMapper">
 
     <!-- 澶氱粨鏋勫祵濂楄嚜鍔ㄦ槧灏勯渶甯︿笂姣忎釜瀹炰綋鐨勪富閿甶d 鍚﹀垯鏄犲皠浼氬け璐� -->
-    <resultMap type="com.ruoyi.generator.domain.GenTable" id="GenTableResult">
+    <resultMap type="org.dromara.generator.domain.GenTable" id="GenTableResult">
         <id property="tableId" column="table_id" />
         <collection property="columns" javaType="java.util.List" resultMap="GenTableColumnResult" />
     </resultMap>
 
-    <resultMap type="com.ruoyi.generator.domain.GenTableColumn" id="GenTableColumnResult">
+    <resultMap type="org.dromara.generator.domain.GenTableColumn" id="GenTableColumnResult">
         <id property="columnId" column="column_id"/>
     </resultMap>
 
     <select id="selectPageDbTableList" resultMap="GenTableResult">
-        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isMySql()">
+        <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isMySql()">
             select table_name, table_comment, create_time, update_time
             from information_schema.tables
             where table_schema = (select database())
@@ -29,7 +29,7 @@
             </if>
             order by create_time desc
         </if>
-        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isOracle()">
+        <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isOracle()">
             select lower(dt.table_name) as table_name, dtc.comments as table_comment, uo.created as create_time, uo.last_ddl_time as update_time
             from user_tables dt, user_tab_comments dtc, user_objects uo
             where dt.table_name = dtc.table_name
@@ -45,7 +45,7 @@
             </if>
             order by create_time desc
         </if>
-        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isPostgerSql()">
+        <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isPostgerSql()">
             select table_name, table_comment, create_time, update_time
             from (
                 SELECT c.relname AS table_name,
@@ -69,7 +69,7 @@
             </if>
             order by create_time desc
         </if>
-        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isSqlServer()">
+        <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isSqlServer()">
             SELECT cast(D.NAME as nvarchar) as table_name,
                    cast(F.VALUE as nvarchar) as table_comment,
                    crdate as create_time,
@@ -90,7 +90,7 @@
     </select>
 
     <select id="selectDbTableListByNames" resultMap="GenTableResult">
-        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isMySql()">
+        <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isMySql()">
             select table_name, table_comment, create_time, update_time from information_schema.tables
             where table_name NOT LIKE 'xxl_job_%' and table_name NOT LIKE 'gen_%' and table_schema = (select database())
             and table_name in
@@ -98,7 +98,7 @@
                  #{name}
             </foreach>
         </if>
-        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isOracle()">
+        <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isOracle()">
             select lower(dt.table_name) as table_name, dtc.comments as table_comment, uo.created as create_time, uo.last_ddl_time as update_time
             from user_tables dt, user_tab_comments dtc, user_objects uo
             where dt.table_name = dtc.table_name
@@ -111,7 +111,7 @@
                 #{name}
             </foreach>
         </if>
-        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isPostgerSql()">
+        <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isPostgerSql()">
             select table_name, table_comment, create_time, update_time
             from (
                 SELECT c.relname AS table_name,
@@ -131,7 +131,7 @@
                 #{name}
             </foreach>
         </if>
-        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isSqlServer()">
+        <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isSqlServer()">
             SELECT cast(D.NAME as nvarchar) as table_name,
                    cast(F.VALUE as nvarchar) as table_comment,
                    crdate as create_time,
@@ -148,12 +148,12 @@
     </select>
 
     <select id="selectTableByName" parameterType="String" resultMap="GenTableResult">
-        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isMySql()">
+        <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isMySql()">
             select table_name, table_comment, create_time, update_time from information_schema.tables
             where table_name NOT LIKE 'xxl_job_%' and table_name NOT LIKE 'gen_%' and table_schema = (select database())
             and table_name = #{tableName}
         </if>
-        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isOracle()">
+        <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isOracle()">
             select lower(dt.table_name) as table_name, dtc.comments as table_comment, uo.created as create_time, uo.last_ddl_time as update_time
             from user_tables dt, user_tab_comments dtc, user_objects uo
             where dt.table_name = dtc.table_name
@@ -163,7 +163,7 @@
             AND dt.table_name NOT IN (select table_name from gen_table)
             and lower(dt.table_name) = #{tableName}
         </if>
-        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isPostgerSql()">
+        <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isPostgerSql()">
             select table_name, table_comment, create_time, update_time
             from (
                 SELECT c.relname AS table_name,
@@ -180,7 +180,7 @@
             where table_name NOT LIKE 'xxl_job_%' and table_name NOT LIKE 'gen_%'
             and table_name = #{tableName}
         </if>
-        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isSqlServer()">
+        <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isSqlServer()">
             SELECT cast(D.NAME as nvarchar) as table_name,
                    cast(F.VALUE as nvarchar) as table_comment,
                    crdate as create_time,
diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/bo.java.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/bo.java.vm
index e4bba01..6b789db 100644
--- a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/bo.java.vm
+++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/bo.java.vm
@@ -1,9 +1,7 @@
 package ${packageName}.domain.bo;
 
 import ${packageName}.domain.${ClassName};
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-import com.ruoyi.common.core.validate.AddGroup;
-import com.ruoyi.common.core.validate.EditGroup;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
 import io.github.linpeilie.annotations.AutoMapper;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
@@ -11,8 +9,6 @@
 #foreach ($import in $importList)
 import ${import};
 #end
-
-import java.util.Date;
 
 /**
  * ${functionName}涓氬姟瀵硅薄 ${tableName}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/controller.java.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/controller.java.vm
index 761284f..8275df4 100644
--- a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/controller.java.vm
+++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/controller.java.vm
@@ -1,8 +1,6 @@
 package ${packageName}.controller;
 
 import java.util.List;
-import java.util.Arrays;
-import java.util.concurrent.TimeUnit;
 
 import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
@@ -10,20 +8,20 @@
 import cn.dev33.satoken.annotation.SaCheckPermission;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.validation.annotation.Validated;
-import com.ruoyi.common.idempotent.annotation.RepeatSubmit;
-import com.ruoyi.common.log.annotation.Log;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.core.validate.AddGroup;
-import com.ruoyi.common.core.validate.EditGroup;
-import com.ruoyi.common.log.enums.BusinessType;
-import com.ruoyi.common.excel.utils.ExcelUtil;
+import annotation.idempotent.common.org.dromara.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import utils.excel.common.org.dromara.ExcelUtil;
 import ${packageName}.domain.vo.${ClassName}Vo;
 import ${packageName}.domain.bo.${ClassName}Bo;
 import ${packageName}.service.I${ClassName}Service;
 #if($table.crud || $table.sub)
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
 #elseif($table.tree)
 #end
 
diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/domain.java.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/domain.java.vm
index f176ecd..ba3a7bd 100644
--- a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/domain.java.vm
+++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/domain.java.vm
@@ -6,9 +6,8 @@
 #end
 #end
 #if($IsTenant==1)
-import com.ruoyi.common.tenant.core.TenantEntity;
+import core.tenant.common.org.dromara.TenantEntity;
 #else
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
 #end
 import com.baomidou.mybatisplus.annotation.*;
 import lombok.Data;
@@ -18,8 +17,6 @@
 #end
 
 import java.io.Serial;
-import java.util.Date;
-import java.math.BigDecimal;
 
 /**
  * ${functionName}瀵硅薄 ${tableName}
diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm
index 10ace3a..0922401 100644
--- a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm
+++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm
@@ -2,7 +2,7 @@
 
 import ${packageName}.domain.${ClassName};
 import ${packageName}.domain.vo.${ClassName}Vo;
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
 
 /**
  * ${functionName}Mapper鎺ュ彛
diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/service.java.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/service.java.vm
index 6527c93..d596a0e 100644
--- a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/service.java.vm
+++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/service.java.vm
@@ -4,8 +4,8 @@
 import ${packageName}.domain.vo.${ClassName}Vo;
 import ${packageName}.domain.bo.${ClassName}Bo;
 #if($table.crud || $table.sub)
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
 #end
 
 import java.util.Collection;
diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm
index 9702aa1..cec6c1b 100644
--- a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm
+++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm
@@ -1,10 +1,9 @@
 package ${packageName}.service.impl;
 
-import com.ruoyi.common.core.utils.MapstructUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-#if($table.crud || $table.sub)
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.utils.MapstructUtils;
+    #if($table.crud || $table.sub)
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 #end
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/vo.java.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/vo.java.vm
index 25b2bad..cd1aeb8 100644
--- a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/vo.java.vm
+++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/vo.java.vm
@@ -6,8 +6,8 @@
 import ${packageName}.domain.${ClassName};
 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
 import com.alibaba.excel.annotation.ExcelProperty;
-import com.ruoyi.common.excel.annotation.ExcelDictFormat;
-import com.ruoyi.common.excel.convert.ExcelDictConvert;
+import annotation.excel.common.org.dromara.ExcelDictFormat;
+import convert.excel.common.org.dromara.ExcelDictConvert;
 import io.github.linpeilie.annotations.AutoMapper;
 import lombok.Data;
 
diff --git a/ruoyi-modules/ruoyi-job/pom.xml b/ruoyi-modules/ruoyi-job/pom.xml
index 08ed731..987b434 100644
--- a/ruoyi-modules/ruoyi-job/pom.xml
+++ b/ruoyi-modules/ruoyi-job/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-modules</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -20,13 +20,13 @@
 
         <!-- 閫氱敤宸ュ叿-->
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-core</artifactId>
         </dependency>
 
         <!-- 璋冨害妯″潡 -->
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-job</artifactId>
         </dependency>
 
diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/SampleService.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/SampleService.java
deleted file mode 100644
index 4ca170b..0000000
--- a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/SampleService.java
+++ /dev/null
@@ -1,252 +0,0 @@
-package com.ruoyi.job.service;
-
-import com.xxl.job.core.context.XxlJobHelper;
-import com.xxl.job.core.handler.annotation.XxlJob;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedReader;
-import java.io.DataOutputStream;
-import java.io.InputStreamReader;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.Arrays;
-
-/**
- * XxlJob寮�鍙戠ず渚嬶紙Bean妯″紡锛�
- * <p>
- * 寮�鍙戞楠わ細
- * 1銆佷换鍔″紑鍙戯細鍦⊿pring Bean瀹炰緥涓紝寮�鍙慗ob鏂规硶锛�
- * 2銆佹敞瑙i厤缃細涓篔ob鏂规硶娣诲姞娉ㄨВ "@XxlJob(value="鑷畾涔塲obhandler鍚嶇О", init = "JobHandler鍒濆鍖栨柟娉�", destroy = "JobHandler閿�姣佹柟娉�")"锛屾敞瑙alue鍊煎搴旂殑鏄皟搴︿腑蹇冩柊寤轰换鍔$殑JobHandler灞炴�х殑鍊笺��
- * 3銆佹墽琛屾棩蹇楋細闇�瑕侀�氳繃 "XxlJobHelper.log" 鎵撳嵃鎵ц鏃ュ織锛�
- * 4銆佷换鍔$粨鏋滐細榛樿浠诲姟缁撴灉涓� "鎴愬姛" 鐘舵�侊紝涓嶉渶瑕佷富鍔ㄨ缃紱濡傛湁璇夋眰锛屾瘮濡傝缃换鍔$粨鏋滀负澶辫触锛屽彲浠ラ�氳繃 "XxlJobHelper.handleFail/handleSuccess" 鑷富璁剧疆浠诲姟缁撴灉锛�
- *
- * @author xuxueli 2019-12-11 21:52:51
- */
-@Slf4j
-@Service
-public class SampleService {
-
-
-    /**
-     * 1銆佺畝鍗曚换鍔$ず渚嬶紙Bean妯″紡锛�
-     */
-    @XxlJob("demoJobHandler")
-    public void demoJobHandler() throws Exception {
-        XxlJobHelper.log("XXL-JOB, Hello World.");
-
-        for (int i = 0; i < 5; i++) {
-            XxlJobHelper.log("beat at:" + i);
-        }
-        // default success
-    }
-
-
-    /**
-     * 2銆佸垎鐗囧箍鎾换鍔�
-     */
-    @XxlJob("shardingJobHandler")
-    public void shardingJobHandler() throws Exception {
-
-        // 鍒嗙墖鍙傛暟
-        int shardIndex = XxlJobHelper.getShardIndex();
-        int shardTotal = XxlJobHelper.getShardTotal();
-
-        XxlJobHelper.log("鍒嗙墖鍙傛暟锛氬綋鍓嶅垎鐗囧簭鍙� = {}, 鎬诲垎鐗囨暟 = {}", shardIndex, shardTotal);
-
-        // 涓氬姟閫昏緫
-        for (int i = 0; i < shardTotal; i++) {
-            if (i == shardIndex) {
-                XxlJobHelper.log("绗� {} 鐗�, 鍛戒腑鍒嗙墖寮�濮嬪鐞�", i);
-            } else {
-                XxlJobHelper.log("绗� {} 鐗�, 蹇界暐", i);
-            }
-        }
-
-    }
-
-
-    /**
-     * 3銆佸懡浠よ浠诲姟
-     */
-    @XxlJob("commandJobHandler")
-    public void commandJobHandler() throws Exception {
-        String command = XxlJobHelper.getJobParam();
-        int exitValue = -1;
-
-        BufferedReader bufferedReader = null;
-        try {
-            // command process
-            ProcessBuilder processBuilder = new ProcessBuilder();
-            processBuilder.command(command);
-            processBuilder.redirectErrorStream(true);
-
-            Process process = processBuilder.start();
-            //Process process = Runtime.getRuntime().exec(command);
-
-            BufferedInputStream bufferedInputStream = new BufferedInputStream(process.getInputStream());
-            bufferedReader = new BufferedReader(new InputStreamReader(bufferedInputStream));
-
-            // command log
-            String line;
-            while ((line = bufferedReader.readLine()) != null) {
-                XxlJobHelper.log(line);
-            }
-
-            // command exit
-            process.waitFor();
-            exitValue = process.exitValue();
-        } catch (Exception e) {
-            XxlJobHelper.log(e);
-        } finally {
-            if (bufferedReader != null) {
-                bufferedReader.close();
-            }
-        }
-
-        if (exitValue == 0) {
-            // default success
-        } else {
-            XxlJobHelper.handleFail("command exit value(" + exitValue + ") is failed");
-        }
-
-    }
-
-
-    /**
-     * 4銆佽法骞冲彴Http浠诲姟
-     * 鍙傛暟绀轰緥锛�
-     * "url: http://www.baidu.com\n" +
-     * "method: get\n" +
-     * "data: content\n";
-     */
-    @XxlJob("httpJobHandler")
-    public void httpJobHandler() throws Exception {
-
-        // param parse
-        String param = XxlJobHelper.getJobParam();
-        if (param == null || param.trim().length() == 0) {
-            XxlJobHelper.log("param[" + param + "] invalid.");
-
-            XxlJobHelper.handleFail();
-            return;
-        }
-
-        String[] httpParams = param.split("\n");
-        String url = null;
-        String method = null;
-        String data = null;
-        for (String httpParam : httpParams) {
-            if (httpParam.startsWith("url:")) {
-                url = httpParam.substring(httpParam.indexOf("url:") + 4).trim();
-            }
-            if (httpParam.startsWith("method:")) {
-                method = httpParam.substring(httpParam.indexOf("method:") + 7).trim().toUpperCase();
-            }
-            if (httpParam.startsWith("data:")) {
-                data = httpParam.substring(httpParam.indexOf("data:") + 5).trim();
-            }
-        }
-
-        // param valid
-        if (url == null || url.trim().length() == 0) {
-            XxlJobHelper.log("url[" + url + "] invalid.");
-
-            XxlJobHelper.handleFail();
-            return;
-        }
-        if (method == null || !Arrays.asList("GET", "POST").contains(method)) {
-            XxlJobHelper.log("method[" + method + "] invalid.");
-
-            XxlJobHelper.handleFail();
-            return;
-        }
-        boolean isPostMethod = method.equals("POST");
-
-        // request
-        HttpURLConnection connection = null;
-        BufferedReader bufferedReader = null;
-        try {
-            // connection
-            URL realUrl = new URL(url);
-            connection = (HttpURLConnection) realUrl.openConnection();
-
-            // connection setting
-            connection.setRequestMethod(method);
-            connection.setDoOutput(isPostMethod);
-            connection.setDoInput(true);
-            connection.setUseCaches(false);
-            connection.setReadTimeout(5 * 1000);
-            connection.setConnectTimeout(3 * 1000);
-            connection.setRequestProperty("connection", "Keep-Alive");
-            connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
-            connection.setRequestProperty("Accept-Charset", "application/json;charset=UTF-8");
-
-            // do connection
-            connection.connect();
-
-            // data
-            if (isPostMethod && data != null && data.trim().length() > 0) {
-                DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());
-                dataOutputStream.write(data.getBytes("UTF-8"));
-                dataOutputStream.flush();
-                dataOutputStream.close();
-            }
-
-            // valid StatusCode
-            int statusCode = connection.getResponseCode();
-            if (statusCode != 200) {
-                throw new RuntimeException("Http Request StatusCode(" + statusCode + ") Invalid.");
-            }
-
-            // result
-            bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
-            StringBuilder result = new StringBuilder();
-            String line;
-            while ((line = bufferedReader.readLine()) != null) {
-                result.append(line);
-            }
-            String responseMsg = result.toString();
-
-            XxlJobHelper.log(responseMsg);
-
-            return;
-        } catch (Exception e) {
-            XxlJobHelper.log(e);
-
-            XxlJobHelper.handleFail();
-            return;
-        } finally {
-            try {
-                if (bufferedReader != null) {
-                    bufferedReader.close();
-                }
-                if (connection != null) {
-                    connection.disconnect();
-                }
-            } catch (Exception e2) {
-                XxlJobHelper.log(e2);
-            }
-        }
-
-    }
-
-    /**
-     * 5銆佺敓鍛藉懆鏈熶换鍔$ず渚嬶細浠诲姟鍒濆鍖栦笌閿�姣佹椂锛屾敮鎸佽嚜瀹氫箟鐩稿叧閫昏緫锛�
-     */
-    @XxlJob(value = "demoJobHandler2", init = "init", destroy = "destroy")
-    public void demoJobHandler2() throws Exception {
-        XxlJobHelper.log("XXL-JOB, Hello World.");
-    }
-
-    public void init() {
-        log.info("init");
-    }
-
-    public void destroy() {
-        log.info("destory");
-    }
-
-
-}
diff --git a/ruoyi-modules/ruoyi-job/src/main/java/org/dromara/job/service/SampleService.java b/ruoyi-modules/ruoyi-job/src/main/java/org/dromara/job/service/SampleService.java
new file mode 100644
index 0000000..4f883e6
--- /dev/null
+++ b/ruoyi-modules/ruoyi-job/src/main/java/org/dromara/job/service/SampleService.java
@@ -0,0 +1,252 @@
+package org.dromara.job.service;
+
+import com.xxl.job.core.context.XxlJobHelper;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Arrays;
+
+/**
+ * XxlJob寮�鍙戠ず渚嬶紙Bean妯″紡锛�
+ * <p>
+ * 寮�鍙戞楠わ細
+ * 1銆佷换鍔″紑鍙戯細鍦⊿pring Bean瀹炰緥涓紝寮�鍙慗ob鏂规硶锛�
+ * 2銆佹敞瑙i厤缃細涓篔ob鏂规硶娣诲姞娉ㄨВ "@XxlJob(value="鑷畾涔塲obhandler鍚嶇О", init = "JobHandler鍒濆鍖栨柟娉�", destroy = "JobHandler閿�姣佹柟娉�")"锛屾敞瑙alue鍊煎搴旂殑鏄皟搴︿腑蹇冩柊寤轰换鍔$殑JobHandler灞炴�х殑鍊笺��
+ * 3銆佹墽琛屾棩蹇楋細闇�瑕侀�氳繃 "XxlJobHelper.log" 鎵撳嵃鎵ц鏃ュ織锛�
+ * 4銆佷换鍔$粨鏋滐細榛樿浠诲姟缁撴灉涓� "鎴愬姛" 鐘舵�侊紝涓嶉渶瑕佷富鍔ㄨ缃紱濡傛湁璇夋眰锛屾瘮濡傝缃换鍔$粨鏋滀负澶辫触锛屽彲浠ラ�氳繃 "XxlJobHelper.handleFail/handleSuccess" 鑷富璁剧疆浠诲姟缁撴灉锛�
+ *
+ * @author xuxueli 2019-12-11 21:52:51
+ */
+@Slf4j
+@Service
+public class SampleService {
+
+
+    /**
+     * 1銆佺畝鍗曚换鍔$ず渚嬶紙Bean妯″紡锛�
+     */
+    @XxlJob("demoJobHandler")
+    public void demoJobHandler() throws Exception {
+        XxlJobHelper.log("XXL-JOB, Hello World.");
+
+        for (int i = 0; i < 5; i++) {
+            XxlJobHelper.log("beat at:" + i);
+        }
+        // default success
+    }
+
+
+    /**
+     * 2銆佸垎鐗囧箍鎾换鍔�
+     */
+    @XxlJob("shardingJobHandler")
+    public void shardingJobHandler() throws Exception {
+
+        // 鍒嗙墖鍙傛暟
+        int shardIndex = XxlJobHelper.getShardIndex();
+        int shardTotal = XxlJobHelper.getShardTotal();
+
+        XxlJobHelper.log("鍒嗙墖鍙傛暟锛氬綋鍓嶅垎鐗囧簭鍙� = {}, 鎬诲垎鐗囨暟 = {}", shardIndex, shardTotal);
+
+        // 涓氬姟閫昏緫
+        for (int i = 0; i < shardTotal; i++) {
+            if (i == shardIndex) {
+                XxlJobHelper.log("绗� {} 鐗�, 鍛戒腑鍒嗙墖寮�濮嬪鐞�", i);
+            } else {
+                XxlJobHelper.log("绗� {} 鐗�, 蹇界暐", i);
+            }
+        }
+
+    }
+
+
+    /**
+     * 3銆佸懡浠よ浠诲姟
+     */
+    @XxlJob("commandJobHandler")
+    public void commandJobHandler() throws Exception {
+        String command = XxlJobHelper.getJobParam();
+        int exitValue = -1;
+
+        BufferedReader bufferedReader = null;
+        try {
+            // command process
+            ProcessBuilder processBuilder = new ProcessBuilder();
+            processBuilder.command(command);
+            processBuilder.redirectErrorStream(true);
+
+            Process process = processBuilder.start();
+            //Process process = Runtime.getRuntime().exec(command);
+
+            BufferedInputStream bufferedInputStream = new BufferedInputStream(process.getInputStream());
+            bufferedReader = new BufferedReader(new InputStreamReader(bufferedInputStream));
+
+            // command log
+            String line;
+            while ((line = bufferedReader.readLine()) != null) {
+                XxlJobHelper.log(line);
+            }
+
+            // command exit
+            process.waitFor();
+            exitValue = process.exitValue();
+        } catch (Exception e) {
+            XxlJobHelper.log(e);
+        } finally {
+            if (bufferedReader != null) {
+                bufferedReader.close();
+            }
+        }
+
+        if (exitValue == 0) {
+            // default success
+        } else {
+            XxlJobHelper.handleFail("command exit value(" + exitValue + ") is failed");
+        }
+
+    }
+
+
+    /**
+     * 4銆佽法骞冲彴Http浠诲姟
+     * 鍙傛暟绀轰緥锛�
+     * "url: http://www.baidu.com\n" +
+     * "method: get\n" +
+     * "data: content\n";
+     */
+    @XxlJob("httpJobHandler")
+    public void httpJobHandler() throws Exception {
+
+        // param parse
+        String param = XxlJobHelper.getJobParam();
+        if (param == null || param.trim().length() == 0) {
+            XxlJobHelper.log("param[" + param + "] invalid.");
+
+            XxlJobHelper.handleFail();
+            return;
+        }
+
+        String[] httpParams = param.split("\n");
+        String url = null;
+        String method = null;
+        String data = null;
+        for (String httpParam : httpParams) {
+            if (httpParam.startsWith("url:")) {
+                url = httpParam.substring(httpParam.indexOf("url:") + 4).trim();
+            }
+            if (httpParam.startsWith("method:")) {
+                method = httpParam.substring(httpParam.indexOf("method:") + 7).trim().toUpperCase();
+            }
+            if (httpParam.startsWith("data:")) {
+                data = httpParam.substring(httpParam.indexOf("data:") + 5).trim();
+            }
+        }
+
+        // param valid
+        if (url == null || url.trim().length() == 0) {
+            XxlJobHelper.log("url[" + url + "] invalid.");
+
+            XxlJobHelper.handleFail();
+            return;
+        }
+        if (method == null || !Arrays.asList("GET", "POST").contains(method)) {
+            XxlJobHelper.log("method[" + method + "] invalid.");
+
+            XxlJobHelper.handleFail();
+            return;
+        }
+        boolean isPostMethod = method.equals("POST");
+
+        // request
+        HttpURLConnection connection = null;
+        BufferedReader bufferedReader = null;
+        try {
+            // connection
+            URL realUrl = new URL(url);
+            connection = (HttpURLConnection) realUrl.openConnection();
+
+            // connection setting
+            connection.setRequestMethod(method);
+            connection.setDoOutput(isPostMethod);
+            connection.setDoInput(true);
+            connection.setUseCaches(false);
+            connection.setReadTimeout(5 * 1000);
+            connection.setConnectTimeout(3 * 1000);
+            connection.setRequestProperty("connection", "Keep-Alive");
+            connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
+            connection.setRequestProperty("Accept-Charset", "application/json;charset=UTF-8");
+
+            // do connection
+            connection.connect();
+
+            // data
+            if (isPostMethod && data != null && data.trim().length() > 0) {
+                DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());
+                dataOutputStream.write(data.getBytes("UTF-8"));
+                dataOutputStream.flush();
+                dataOutputStream.close();
+            }
+
+            // valid StatusCode
+            int statusCode = connection.getResponseCode();
+            if (statusCode != 200) {
+                throw new RuntimeException("Http Request StatusCode(" + statusCode + ") Invalid.");
+            }
+
+            // result
+            bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
+            StringBuilder result = new StringBuilder();
+            String line;
+            while ((line = bufferedReader.readLine()) != null) {
+                result.append(line);
+            }
+            String responseMsg = result.toString();
+
+            XxlJobHelper.log(responseMsg);
+
+            return;
+        } catch (Exception e) {
+            XxlJobHelper.log(e);
+
+            XxlJobHelper.handleFail();
+            return;
+        } finally {
+            try {
+                if (bufferedReader != null) {
+                    bufferedReader.close();
+                }
+                if (connection != null) {
+                    connection.disconnect();
+                }
+            } catch (Exception e2) {
+                XxlJobHelper.log(e2);
+            }
+        }
+
+    }
+
+    /**
+     * 5銆佺敓鍛藉懆鏈熶换鍔$ず渚嬶細浠诲姟鍒濆鍖栦笌閿�姣佹椂锛屾敮鎸佽嚜瀹氫箟鐩稿叧閫昏緫锛�
+     */
+    @XxlJob(value = "demoJobHandler2", init = "init", destroy = "destroy")
+    public void demoJobHandler2() throws Exception {
+        XxlJobHelper.log("XXL-JOB, Hello World.");
+    }
+
+    public void init() {
+        log.info("init");
+    }
+
+    public void destroy() {
+        log.info("destory");
+    }
+
+
+}
diff --git a/ruoyi-modules/ruoyi-system/pom.xml b/ruoyi-modules/ruoyi-system/pom.xml
index be1c3ce..c587ab9 100644
--- a/ruoyi-modules/ruoyi-system/pom.xml
+++ b/ruoyi-modules/ruoyi-system/pom.xml
@@ -3,7 +3,7 @@
          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>
-        <groupId>com.ruoyi</groupId>
+        <groupId>org.dromara</groupId>
         <artifactId>ruoyi-modules</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -19,70 +19,70 @@
     <dependencies>
         <!-- 閫氱敤宸ュ叿-->
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-core</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-doc</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-mybatis</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-translation</artifactId>
         </dependency>
 
         <!-- OSS鍔熻兘妯″潡 -->
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-oss</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-log</artifactId>
         </dependency>
 
         <!-- excel-->
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-excel</artifactId>
         </dependency>
 
         <!-- SMS鍔熻兘妯″潡 -->
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-sms</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-tenant</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-security</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-web</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-idempotent</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>com.ruoyi</groupId>
+            <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-sensitive</artifactId>
         </dependency>
     </dependencies>
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/monitor/CacheController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/monitor/CacheController.java
deleted file mode 100644
index 33d5cb6..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/monitor/CacheController.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.ruoyi.system.controller.monitor;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.system.domain.vo.CacheListInfoVo;
-import lombok.RequiredArgsConstructor;
-import org.redisson.spring.data.connection.RedissonConnectionFactory;
-import org.springframework.data.redis.connection.RedisConnection;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.util.*;
-
-/**
- * 缂撳瓨鐩戞帶
- *
- * @author Lion Li
- */
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/monitor/cache")
-public class CacheController {
-
-    private final RedissonConnectionFactory connectionFactory;
-
-    /**
-     * 鑾峰彇缂撳瓨鐩戞帶鍒楄〃
-     */
-    @SaCheckPermission("monitor:cache:list")
-    @GetMapping()
-    public R<CacheListInfoVo> getInfo() throws Exception {
-        RedisConnection connection = connectionFactory.getConnection();
-        Properties commandStats = connection.commands().info("commandstats");
-
-        List<Map<String, String>> pieList = new ArrayList<>();
-        if (commandStats != null) {
-            commandStats.stringPropertyNames().forEach(key -> {
-                Map<String, String> data = new HashMap<>(2);
-                String property = commandStats.getProperty(key);
-                data.put("name", StringUtils.removeStart(key, "cmdstat_"));
-                data.put("value", StringUtils.substringBetween(property, "calls=", ",usec"));
-                pieList.add(data);
-            });
-        }
-
-        CacheListInfoVo infoVo = new CacheListInfoVo();
-        infoVo.setInfo(connection.commands().info());
-        infoVo.setDbSize(connection.commands().dbSize());
-        infoVo.setCommandStats(pieList);
-        return R.ok(infoVo);
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/monitor/SysLogininforController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/monitor/SysLogininforController.java
deleted file mode 100644
index 1ef7f7f..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/monitor/SysLogininforController.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package com.ruoyi.system.controller.monitor;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import com.ruoyi.common.core.constant.GlobalConstants;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.excel.utils.ExcelUtil;
-import com.ruoyi.common.log.annotation.Log;
-import com.ruoyi.common.log.enums.BusinessType;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.redis.utils.RedisUtils;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.system.domain.bo.SysLogininforBo;
-import com.ruoyi.system.domain.vo.SysLogininforVo;
-import com.ruoyi.system.service.ISysLogininforService;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.RequiredArgsConstructor;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-/**
- * 绯荤粺璁块棶璁板綍
- *
- * @author Lion Li
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/monitor/logininfor")
-public class SysLogininforController extends BaseController {
-
-    private final ISysLogininforService logininforService;
-
-    /**
-     * 鑾峰彇绯荤粺璁块棶璁板綍鍒楄〃
-     */
-    @SaCheckPermission("monitor:logininfor:list")
-    @GetMapping("/list")
-    public TableDataInfo<SysLogininforVo> list(SysLogininforBo logininfor, PageQuery pageQuery) {
-        return logininforService.selectPageLogininforList(logininfor, pageQuery);
-    }
-
-    /**
-     * 瀵煎嚭绯荤粺璁块棶璁板綍鍒楄〃
-     */
-    @Log(title = "鐧诲綍鏃ュ織", businessType = BusinessType.EXPORT)
-    @SaCheckPermission("monitor:logininfor:export")
-    @PostMapping("/export")
-    public void export(SysLogininforBo logininfor, HttpServletResponse response) {
-        List<SysLogininforVo> list = logininforService.selectLogininforList(logininfor);
-        ExcelUtil.exportExcel(list, "鐧诲綍鏃ュ織", SysLogininforVo.class, response);
-    }
-
-    /**
-     * 鎵归噺鍒犻櫎鐧诲綍鏃ュ織
-     * @param infoIds 鏃ュ織ids
-     */
-    @SaCheckPermission("monitor:logininfor:remove")
-    @Log(title = "鐧诲綍鏃ュ織", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{infoIds}")
-    public R<Void> remove(@PathVariable Long[] infoIds) {
-        return toAjax(logininforService.deleteLogininforByIds(infoIds));
-    }
-
-    /**
-     * 娓呯悊绯荤粺璁块棶璁板綍
-     */
-    @SaCheckPermission("monitor:logininfor:remove")
-    @Log(title = "鐧诲綍鏃ュ織", businessType = BusinessType.CLEAN)
-    @DeleteMapping("/clean")
-    public R<Void> clean() {
-        logininforService.cleanLogininfor();
-        return R.ok();
-    }
-
-    @SaCheckPermission("monitor:logininfor:unlock")
-    @Log(title = "璐︽埛瑙i攣", businessType = BusinessType.OTHER)
-    @GetMapping("/unlock/{userName}")
-    public R<Void> unlock(@PathVariable("userName") String userName) {
-        String loginName = GlobalConstants.PWD_ERR_CNT_KEY + userName;
-        if (RedisUtils.hasKey(loginName)) {
-            RedisUtils.deleteObject(loginName);
-        }
-        return R.ok();
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/monitor/SysOperlogController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/monitor/SysOperlogController.java
deleted file mode 100644
index 2793890..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/monitor/SysOperlogController.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package com.ruoyi.system.controller.monitor;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import com.ruoyi.common.log.annotation.Log;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.log.enums.BusinessType;
-import com.ruoyi.common.excel.utils.ExcelUtil;
-import com.ruoyi.system.domain.bo.SysOperLogBo;
-import com.ruoyi.system.domain.vo.SysOperLogVo;
-import com.ruoyi.system.service.ISysOperLogService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import jakarta.servlet.http.HttpServletResponse;
-import java.util.List;
-
-/**
- * 鎿嶄綔鏃ュ織璁板綍
- *
- * @author Lion Li
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/monitor/operlog")
-public class SysOperlogController extends BaseController {
-
-    private final ISysOperLogService operLogService;
-
-    /**
-     * 鑾峰彇鎿嶄綔鏃ュ織璁板綍鍒楄〃
-     */
-    @SaCheckPermission("monitor:operlog:list")
-    @GetMapping("/list")
-    public TableDataInfo<SysOperLogVo> list(SysOperLogBo operLog, PageQuery pageQuery) {
-        return operLogService.selectPageOperLogList(operLog, pageQuery);
-    }
-
-    /**
-     * 瀵煎嚭鎿嶄綔鏃ュ織璁板綍鍒楄〃
-     */
-    @Log(title = "鎿嶄綔鏃ュ織", businessType = BusinessType.EXPORT)
-    @SaCheckPermission("monitor:operlog:export")
-    @PostMapping("/export")
-    public void export(SysOperLogBo operLog, HttpServletResponse response) {
-        List<SysOperLogVo> list = operLogService.selectOperLogList(operLog);
-        ExcelUtil.exportExcel(list, "鎿嶄綔鏃ュ織", SysOperLogVo.class, response);
-    }
-
-    /**
-     * 鎵归噺鍒犻櫎鎿嶄綔鏃ュ織璁板綍
-     * @param operIds 鏃ュ織ids
-     */
-    @Log(title = "鎿嶄綔鏃ュ織", businessType = BusinessType.DELETE)
-    @SaCheckPermission("monitor:operlog:remove")
-    @DeleteMapping("/{operIds}")
-    public R<Void> remove(@PathVariable Long[] operIds) {
-        return toAjax(operLogService.deleteOperLogByIds(operIds));
-    }
-
-    /**
-     * 娓呯悊鎿嶄綔鏃ュ織璁板綍
-     */
-    @Log(title = "鎿嶄綔鏃ュ織", businessType = BusinessType.CLEAN)
-    @SaCheckPermission("monitor:operlog:remove")
-    @DeleteMapping("/clean")
-    public R<Void> clean() {
-        operLogService.cleanOperLog();
-        return R.ok();
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/monitor/SysUserOnlineController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/monitor/SysUserOnlineController.java
deleted file mode 100644
index 9daa394..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/monitor/SysUserOnlineController.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package com.ruoyi.system.controller.monitor;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import cn.dev33.satoken.exception.NotLoginException;
-import cn.dev33.satoken.stp.StpUtil;
-import cn.hutool.core.bean.BeanUtil;
-import com.ruoyi.common.core.constant.CacheConstants;
-import com.ruoyi.common.core.constant.GlobalConstants;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.core.domain.dto.UserOnlineDTO;
-import com.ruoyi.common.core.utils.StreamUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.log.annotation.Log;
-import com.ruoyi.common.log.enums.BusinessType;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.redis.utils.RedisUtils;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.system.domain.SysUserOnline;
-import lombok.RequiredArgsConstructor;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * 鍦ㄧ嚎鐢ㄦ埛鐩戞帶
- *
- * @author Lion Li
- */
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/monitor/online")
-public class SysUserOnlineController extends BaseController {
-
-    /**
-     * 鑾峰彇鍦ㄧ嚎鐢ㄦ埛鐩戞帶鍒楄〃
-     *
-     * @param ipaddr   IP鍦板潃
-     * @param userName 鐢ㄦ埛鍚�
-     */
-    @SaCheckPermission("monitor:online:list")
-    @GetMapping("/list")
-    public TableDataInfo<SysUserOnline> list(String ipaddr, String userName) {
-        // 鑾峰彇鎵�鏈夋湭杩囨湡鐨� token
-        List<String> keys = StpUtil.searchTokenValue("", 0, -1, false);
-        List<UserOnlineDTO> userOnlineDTOList = new ArrayList<>();
-        for (String key : keys) {
-            String token = key.replace(GlobalConstants.LOGIN_TOKEN_KEY, "");
-            // 濡傛灉宸茬粡杩囨湡鍒欒烦杩�
-            if (StpUtil.stpLogic.getTokenActivityTimeoutByToken(token) < -1) {
-                continue;
-            }
-            userOnlineDTOList.add(RedisUtils.getCacheObject(CacheConstants.ONLINE_TOKEN_KEY + token));
-        }
-        if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) {
-            userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
-                StringUtils.equals(ipaddr, userOnline.getIpaddr()) &&
-                    StringUtils.equals(userName, userOnline.getUserName())
-            );
-        } else if (StringUtils.isNotEmpty(ipaddr)) {
-            userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
-                StringUtils.equals(ipaddr, userOnline.getIpaddr())
-            );
-        } else if (StringUtils.isNotEmpty(userName)) {
-            userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
-                StringUtils.equals(userName, userOnline.getUserName())
-            );
-        }
-        Collections.reverse(userOnlineDTOList);
-        userOnlineDTOList.removeAll(Collections.singleton(null));
-        List<SysUserOnline> userOnlineList = BeanUtil.copyToList(userOnlineDTOList, SysUserOnline.class);
-        return TableDataInfo.build(userOnlineList);
-    }
-
-    /**
-     * 寮洪��鐢ㄦ埛
-     *
-     * @param tokenId token鍊�
-     */
-    @SaCheckPermission("monitor:online:forceLogout")
-    @Log(title = "鍦ㄧ嚎鐢ㄦ埛", businessType = BusinessType.FORCE)
-    @DeleteMapping("/{tokenId}")
-    public R<Void> forceLogout(@PathVariable String tokenId) {
-        try {
-            StpUtil.kickoutByTokenValue(tokenId);
-        } catch (NotLoginException ignored) {
-        }
-        return R.ok();
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysConfigController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysConfigController.java
deleted file mode 100644
index b805911..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysConfigController.java
+++ /dev/null
@@ -1,137 +0,0 @@
-package com.ruoyi.system.controller.system;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.excel.utils.ExcelUtil;
-import com.ruoyi.common.log.annotation.Log;
-import com.ruoyi.common.log.enums.BusinessType;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.system.domain.bo.SysConfigBo;
-import com.ruoyi.system.domain.vo.SysConfigVo;
-import com.ruoyi.system.service.ISysConfigService;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.RequiredArgsConstructor;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-/**
- * 鍙傛暟閰嶇疆 淇℃伅鎿嶄綔澶勭悊
- *
- * @author Lion Li
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/system/config")
-public class SysConfigController extends BaseController {
-
-    private final ISysConfigService configService;
-
-    /**
-     * 鑾峰彇鍙傛暟閰嶇疆鍒楄〃
-     */
-    @SaCheckPermission("system:config:list")
-    @GetMapping("/list")
-    public TableDataInfo<SysConfigVo> list(SysConfigBo config, PageQuery pageQuery) {
-        return configService.selectPageConfigList(config, pageQuery);
-    }
-
-    /**
-     * 瀵煎嚭鍙傛暟閰嶇疆鍒楄〃
-     */
-    @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.EXPORT)
-    @SaCheckPermission("system:config:export")
-    @PostMapping("/export")
-    public void export(SysConfigBo config, HttpServletResponse response) {
-        List<SysConfigVo> list = configService.selectConfigList(config);
-        ExcelUtil.exportExcel(list, "鍙傛暟鏁版嵁", SysConfigVo.class, response);
-    }
-
-    /**
-     * 鏍规嵁鍙傛暟缂栧彿鑾峰彇璇︾粏淇℃伅
-     *
-     * @param configId 鍙傛暟ID
-     */
-    @SaCheckPermission("system:config:query")
-    @GetMapping(value = "/{configId}")
-    public R<SysConfigVo> getInfo(@PathVariable Long configId) {
-        return R.ok(configService.selectConfigById(configId));
-    }
-
-    /**
-     * 鏍规嵁鍙傛暟閿悕鏌ヨ鍙傛暟鍊�
-     *
-     * @param configKey 鍙傛暟Key
-     */
-    @GetMapping(value = "/configKey/{configKey}")
-    public R<Void> getConfigKey(@PathVariable String configKey) {
-        return R.ok(configService.selectConfigByKey(configKey));
-    }
-
-    /**
-     * 鏂板鍙傛暟閰嶇疆
-     */
-    @SaCheckPermission("system:config:add")
-    @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.INSERT)
-    @PostMapping
-    public R<Void> add(@Validated @RequestBody SysConfigBo config) {
-        if (!configService.checkConfigKeyUnique(config)) {
-            return R.fail("鏂板鍙傛暟'" + config.getConfigName() + "'澶辫触锛屽弬鏁伴敭鍚嶅凡瀛樺湪");
-        }
-        configService.insertConfig(config);
-        return R.ok();
-    }
-
-    /**
-     * 淇敼鍙傛暟閰嶇疆
-     */
-    @SaCheckPermission("system:config:edit")
-    @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.UPDATE)
-    @PutMapping
-    public R<Void> edit(@Validated @RequestBody SysConfigBo config) {
-        if (!configService.checkConfigKeyUnique(config)) {
-            return R.fail("淇敼鍙傛暟'" + config.getConfigName() + "'澶辫触锛屽弬鏁伴敭鍚嶅凡瀛樺湪");
-        }
-        configService.updateConfig(config);
-        return R.ok();
-    }
-
-    /**
-     * 鏍规嵁鍙傛暟閿悕淇敼鍙傛暟閰嶇疆
-     */
-    @SaCheckPermission("system:config:edit")
-    @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.UPDATE)
-    @PutMapping("/updateByKey")
-    public R<Void> updateByKey(@RequestBody SysConfigBo config) {
-        configService.updateConfig(config);
-        return R.ok();
-    }
-
-    /**
-     * 鍒犻櫎鍙傛暟閰嶇疆
-     *
-     * @param configIds 鍙傛暟ID涓�
-     */
-    @SaCheckPermission("system:config:remove")
-    @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{configIds}")
-    public R<Void> remove(@PathVariable Long[] configIds) {
-        configService.deleteConfigByIds(configIds);
-        return R.ok();
-    }
-
-    /**
-     * 鍒锋柊鍙傛暟缂撳瓨
-     */
-    @SaCheckPermission("system:config:remove")
-    @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.CLEAN)
-    @DeleteMapping("/refreshCache")
-    public R<Void> refreshCache() {
-        configService.resetConfigCache();
-        return R.ok();
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysDeptController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysDeptController.java
deleted file mode 100644
index 6caf0df..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysDeptController.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package com.ruoyi.system.controller.system;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import cn.hutool.core.convert.Convert;
-import com.ruoyi.common.core.constant.UserConstants;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.log.annotation.Log;
-import com.ruoyi.common.log.enums.BusinessType;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.system.domain.bo.SysDeptBo;
-import com.ruoyi.system.domain.vo.SysDeptVo;
-import com.ruoyi.system.service.ISysDeptService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-/**
- * 閮ㄩ棬淇℃伅
- *
- * @author Lion Li
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/system/dept")
-public class SysDeptController extends BaseController {
-
-    private final ISysDeptService deptService;
-
-    /**
-     * 鑾峰彇閮ㄩ棬鍒楄〃
-     */
-    @SaCheckPermission("system:dept:list")
-    @GetMapping("/list")
-    public R<List<SysDeptVo>> list(SysDeptBo dept) {
-        List<SysDeptVo> depts = deptService.selectDeptList(dept);
-        return R.ok(depts);
-    }
-
-    /**
-     * 鏌ヨ閮ㄩ棬鍒楄〃锛堟帓闄よ妭鐐癸級
-     *
-     * @param deptId 閮ㄩ棬ID
-     */
-    @SaCheckPermission("system:dept:list")
-    @GetMapping("/list/exclude/{deptId}")
-    public R<List<SysDeptVo>> excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) {
-        List<SysDeptVo> depts = deptService.selectDeptList(new SysDeptBo());
-        depts.removeIf(d -> d.getDeptId().equals(deptId)
-            || StringUtils.splitList(d.getAncestors()).contains(Convert.toStr(deptId)));
-        return R.ok(depts);
-    }
-
-    /**
-     * 鏍规嵁閮ㄩ棬缂栧彿鑾峰彇璇︾粏淇℃伅
-     *
-     * @param deptId 閮ㄩ棬ID
-     */
-    @SaCheckPermission("system:dept:query")
-    @GetMapping(value = "/{deptId}")
-    public R<SysDeptVo> getInfo(@PathVariable Long deptId) {
-        deptService.checkDeptDataScope(deptId);
-        return R.ok(deptService.selectDeptById(deptId));
-    }
-
-    /**
-     * 鏂板閮ㄩ棬
-     */
-    @SaCheckPermission("system:dept:add")
-    @Log(title = "閮ㄩ棬绠$悊", businessType = BusinessType.INSERT)
-    @PostMapping
-    public R<Void> add(@Validated @RequestBody SysDeptBo dept) {
-        if (!deptService.checkDeptNameUnique(dept)) {
-            return R.fail("鏂板閮ㄩ棬'" + dept.getDeptName() + "'澶辫触锛岄儴闂ㄥ悕绉板凡瀛樺湪");
-        }
-        return toAjax(deptService.insertDept(dept));
-    }
-
-    /**
-     * 淇敼閮ㄩ棬
-     */
-    @SaCheckPermission("system:dept:edit")
-    @Log(title = "閮ㄩ棬绠$悊", businessType = BusinessType.UPDATE)
-    @PutMapping
-    public R<Void> edit(@Validated @RequestBody SysDeptBo dept) {
-        Long deptId = dept.getDeptId();
-        deptService.checkDeptDataScope(deptId);
-        if (!deptService.checkDeptNameUnique(dept)) {
-            return R.fail("淇敼閮ㄩ棬'" + dept.getDeptName() + "'澶辫触锛岄儴闂ㄥ悕绉板凡瀛樺湪");
-        } else if (dept.getParentId().equals(deptId)) {
-            return R.fail("淇敼閮ㄩ棬'" + dept.getDeptName() + "'澶辫触锛屼笂绾ч儴闂ㄤ笉鑳芥槸鑷繁");
-        } else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus())
-            && deptService.selectNormalChildrenDeptById(deptId) > 0) {
-            return R.fail("璇ラ儴闂ㄥ寘鍚湭鍋滅敤鐨勫瓙閮ㄩ棬锛�");
-        }
-        return toAjax(deptService.updateDept(dept));
-    }
-
-    /**
-     * 鍒犻櫎閮ㄩ棬
-     *
-     * @param deptId 閮ㄩ棬ID
-     */
-    @SaCheckPermission("system:dept:remove")
-    @Log(title = "閮ㄩ棬绠$悊", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{deptId}")
-    public R<Void> remove(@PathVariable Long deptId) {
-        if (deptService.hasChildByDeptId(deptId)) {
-            return R.warn("瀛樺湪涓嬬骇閮ㄩ棬,涓嶅厑璁稿垹闄�");
-        }
-        if (deptService.checkDeptExistUser(deptId)) {
-            return R.warn("閮ㄩ棬瀛樺湪鐢ㄦ埛,涓嶅厑璁稿垹闄�");
-        }
-        deptService.checkDeptDataScope(deptId);
-        return toAjax(deptService.deleteDeptById(deptId));
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysDictDataController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysDictDataController.java
deleted file mode 100644
index 5cc5e89..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysDictDataController.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package com.ruoyi.system.controller.system;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import cn.hutool.core.util.ObjectUtil;
-import com.ruoyi.common.log.annotation.Log;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.system.domain.SysDictData;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.log.enums.BusinessType;
-import com.ruoyi.common.excel.utils.ExcelUtil;
-import com.ruoyi.system.domain.bo.SysDictDataBo;
-import com.ruoyi.system.domain.vo.SysDictDataVo;
-import com.ruoyi.system.service.ISysDictDataService;
-import com.ruoyi.system.service.ISysDictTypeService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import jakarta.servlet.http.HttpServletResponse;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * 鏁版嵁瀛楀吀淇℃伅
- *
- * @author Lion Li
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/system/dict/data")
-public class SysDictDataController extends BaseController {
-
-    private final ISysDictDataService dictDataService;
-    private final ISysDictTypeService dictTypeService;
-
-    /**
-     * 鏌ヨ瀛楀吀鏁版嵁鍒楄〃
-     */
-    @SaCheckPermission("system:dict:list")
-    @GetMapping("/list")
-    public TableDataInfo<SysDictDataVo> list(SysDictDataBo dictData, PageQuery pageQuery) {
-        return dictDataService.selectPageDictDataList(dictData, pageQuery);
-    }
-
-    /**
-     * 瀵煎嚭瀛楀吀鏁版嵁鍒楄〃
-     */
-    @Log(title = "瀛楀吀鏁版嵁", businessType = BusinessType.EXPORT)
-    @SaCheckPermission("system:dict:export")
-    @PostMapping("/export")
-    public void export(SysDictDataBo dictData, HttpServletResponse response) {
-        List<SysDictDataVo> list = dictDataService.selectDictDataList(dictData);
-        ExcelUtil.exportExcel(list, "瀛楀吀鏁版嵁", SysDictDataVo.class, response);
-    }
-
-    /**
-     * 鏌ヨ瀛楀吀鏁版嵁璇︾粏
-     *
-     * @param dictCode 瀛楀吀code
-     */
-    @SaCheckPermission("system:dict:query")
-    @GetMapping(value = "/{dictCode}")
-    public R<SysDictDataVo> getInfo(@PathVariable Long dictCode) {
-        return R.ok(dictDataService.selectDictDataById(dictCode));
-    }
-
-    /**
-     * 鏍规嵁瀛楀吀绫诲瀷鏌ヨ瀛楀吀鏁版嵁淇℃伅
-     *
-     * @param dictType 瀛楀吀绫诲瀷
-     */
-    @GetMapping(value = "/type/{dictType}")
-    public R<List<SysDictDataVo>> dictType(@PathVariable String dictType) {
-        List<SysDictDataVo> data = dictTypeService.selectDictDataByType(dictType);
-        if (ObjectUtil.isNull(data)) {
-            data = new ArrayList<>();
-        }
-        return R.ok(data);
-    }
-
-    /**
-     * 鏂板瀛楀吀绫诲瀷
-     */
-    @SaCheckPermission("system:dict:add")
-    @Log(title = "瀛楀吀鏁版嵁", businessType = BusinessType.INSERT)
-    @PostMapping
-    public R<Void> add(@Validated @RequestBody SysDictDataBo dict) {
-        dictDataService.insertDictData(dict);
-        return R.ok();
-    }
-
-    /**
-     * 淇敼淇濆瓨瀛楀吀绫诲瀷
-     */
-    @SaCheckPermission("system:dict:edit")
-    @Log(title = "瀛楀吀鏁版嵁", businessType = BusinessType.UPDATE)
-    @PutMapping
-    public R<Void> edit(@Validated @RequestBody SysDictDataBo dict) {
-        dictDataService.updateDictData(dict);
-        return R.ok();
-    }
-
-    /**
-     * 鍒犻櫎瀛楀吀绫诲瀷
-     *
-     * @param dictCodes 瀛楀吀code涓�
-     */
-    @SaCheckPermission("system:dict:remove")
-    @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{dictCodes}")
-    public R<Void> remove(@PathVariable Long[] dictCodes) {
-        dictDataService.deleteDictDataByIds(dictCodes);
-        return R.ok();
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysDictTypeController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysDictTypeController.java
deleted file mode 100644
index 60ce4b9..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysDictTypeController.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package com.ruoyi.system.controller.system;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.excel.utils.ExcelUtil;
-import com.ruoyi.common.log.annotation.Log;
-import com.ruoyi.common.log.enums.BusinessType;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.system.domain.bo.SysDictTypeBo;
-import com.ruoyi.system.domain.vo.SysDictTypeVo;
-import com.ruoyi.system.service.ISysDictTypeService;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.RequiredArgsConstructor;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-/**
- * 鏁版嵁瀛楀吀淇℃伅
- *
- * @author Lion Li
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/system/dict/type")
-public class SysDictTypeController extends BaseController {
-
-    private final ISysDictTypeService dictTypeService;
-
-    /**
-     * 鏌ヨ瀛楀吀绫诲瀷鍒楄〃
-     */
-    @SaCheckPermission("system:dict:list")
-    @GetMapping("/list")
-    public TableDataInfo<SysDictTypeVo> list(SysDictTypeBo dictType, PageQuery pageQuery) {
-        return dictTypeService.selectPageDictTypeList(dictType, pageQuery);
-    }
-
-    /**
-     * 瀵煎嚭瀛楀吀绫诲瀷鍒楄〃
-     */
-    @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.EXPORT)
-    @SaCheckPermission("system:dict:export")
-    @PostMapping("/export")
-    public void export(SysDictTypeBo dictType, HttpServletResponse response) {
-        List<SysDictTypeVo> list = dictTypeService.selectDictTypeList(dictType);
-        ExcelUtil.exportExcel(list, "瀛楀吀绫诲瀷", SysDictTypeVo.class, response);
-    }
-
-    /**
-     * 鏌ヨ瀛楀吀绫诲瀷璇︾粏
-     *
-     * @param dictId 瀛楀吀ID
-     */
-    @SaCheckPermission("system:dict:query")
-    @GetMapping(value = "/{dictId}")
-    public R<SysDictTypeVo> getInfo(@PathVariable Long dictId) {
-        return R.ok(dictTypeService.selectDictTypeById(dictId));
-    }
-
-    /**
-     * 鏂板瀛楀吀绫诲瀷
-     */
-    @SaCheckPermission("system:dict:add")
-    @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.INSERT)
-    @PostMapping
-    public R<Void> add(@Validated @RequestBody SysDictTypeBo dict) {
-        if (!dictTypeService.checkDictTypeUnique(dict)) {
-            return R.fail("鏂板瀛楀吀'" + dict.getDictName() + "'澶辫触锛屽瓧鍏哥被鍨嬪凡瀛樺湪");
-        }
-        dictTypeService.insertDictType(dict);
-        return R.ok();
-    }
-
-    /**
-     * 淇敼瀛楀吀绫诲瀷
-     */
-    @SaCheckPermission("system:dict:edit")
-    @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.UPDATE)
-    @PutMapping
-    public R<Void> edit(@Validated @RequestBody SysDictTypeBo dict) {
-        if (!dictTypeService.checkDictTypeUnique(dict)) {
-            return R.fail("淇敼瀛楀吀'" + dict.getDictName() + "'澶辫触锛屽瓧鍏哥被鍨嬪凡瀛樺湪");
-        }
-        dictTypeService.updateDictType(dict);
-        return R.ok();
-    }
-
-    /**
-     * 鍒犻櫎瀛楀吀绫诲瀷
-     *
-     * @param dictIds 瀛楀吀ID涓�
-     */
-    @SaCheckPermission("system:dict:remove")
-    @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{dictIds}")
-    public R<Void> remove(@PathVariable Long[] dictIds) {
-        dictTypeService.deleteDictTypeByIds(dictIds);
-        return R.ok();
-    }
-
-    /**
-     * 鍒锋柊瀛楀吀缂撳瓨
-     */
-    @SaCheckPermission("system:dict:remove")
-    @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.CLEAN)
-    @DeleteMapping("/refreshCache")
-    public R<Void> refreshCache() {
-        dictTypeService.resetDictCache();
-        return R.ok();
-    }
-
-    /**
-     * 鑾峰彇瀛楀吀閫夋嫨妗嗗垪琛�
-     */
-    @GetMapping("/optionselect")
-    public R<List<SysDictTypeVo>> optionselect() {
-        List<SysDictTypeVo> dictTypes = dictTypeService.selectDictTypeAll();
-        return R.ok(dictTypes);
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysMenuController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysMenuController.java
deleted file mode 100644
index 2288360..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysMenuController.java
+++ /dev/null
@@ -1,182 +0,0 @@
-package com.ruoyi.system.controller.system;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import cn.dev33.satoken.annotation.SaCheckRole;
-import cn.dev33.satoken.annotation.SaMode;
-import cn.hutool.core.lang.tree.Tree;
-import com.ruoyi.common.core.constant.TenantConstants;
-import com.ruoyi.common.core.constant.UserConstants;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.log.annotation.Log;
-import com.ruoyi.common.log.enums.BusinessType;
-import com.ruoyi.common.satoken.utils.LoginHelper;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.system.domain.SysMenu;
-import com.ruoyi.system.domain.bo.SysMenuBo;
-import com.ruoyi.system.domain.vo.MenuTreeSelectVo;
-import com.ruoyi.system.domain.vo.RouterVo;
-import com.ruoyi.system.domain.vo.SysMenuVo;
-import com.ruoyi.system.service.ISysMenuService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-/**
- * 鑿滃崟淇℃伅
- *
- * @author Lion Li
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/system/menu")
-public class SysMenuController extends BaseController {
-
-    private final ISysMenuService menuService;
-
-    /**
-     * 鑾峰彇璺敱淇℃伅
-     *
-     * @return 璺敱淇℃伅
-     */
-    @GetMapping("/getRouters")
-    public R<List<RouterVo>> getRouters() {
-        List<SysMenu> menus = menuService.selectMenuTreeByUserId(LoginHelper.getUserId());
-        return R.ok(menuService.buildMenus(menus));
-    }
-
-    /**
-     * 鑾峰彇鑿滃崟鍒楄〃
-     */
-    @SaCheckRole(value = {
-            TenantConstants.SUPER_ADMIN_ROLE_KEY,
-            TenantConstants.TENANT_ADMIN_ROLE_KEY
-    }, mode = SaMode.OR)
-    @SaCheckPermission("system:menu:list")
-    @GetMapping("/list")
-    public R<List<SysMenuVo>> list(SysMenuBo menu) {
-        List<SysMenuVo> menus = menuService.selectMenuList(menu, LoginHelper.getUserId());
-        return R.ok(menus);
-    }
-
-    /**
-     * 鏍规嵁鑿滃崟缂栧彿鑾峰彇璇︾粏淇℃伅
-     *
-     * @param menuId 鑿滃崟ID
-     */
-    @SaCheckRole(value = {
-            TenantConstants.SUPER_ADMIN_ROLE_KEY,
-            TenantConstants.TENANT_ADMIN_ROLE_KEY
-    }, mode = SaMode.OR)
-    @SaCheckPermission("system:menu:query")
-    @GetMapping(value = "/{menuId}")
-    public R<SysMenuVo> getInfo(@PathVariable Long menuId) {
-        return R.ok(menuService.selectMenuById(menuId));
-    }
-
-    /**
-     * 鑾峰彇鑿滃崟涓嬫媺鏍戝垪琛�
-     */
-    @SaCheckRole(value = {
-            TenantConstants.SUPER_ADMIN_ROLE_KEY,
-            TenantConstants.TENANT_ADMIN_ROLE_KEY
-    }, mode = SaMode.OR)
-    @SaCheckPermission("system:menu:query")
-    @GetMapping("/treeselect")
-    public R<List<Tree<Long>>> treeselect(SysMenuBo menu) {
-        List<SysMenuVo> menus = menuService.selectMenuList(menu, LoginHelper.getUserId());
-        return R.ok(menuService.buildMenuTreeSelect(menus));
-    }
-
-    /**
-     * 鍔犺浇瀵瑰簲瑙掕壊鑿滃崟鍒楄〃鏍�
-     *
-     * @param roleId 瑙掕壊ID
-     */
-    @SaCheckRole(value = {
-            TenantConstants.SUPER_ADMIN_ROLE_KEY,
-            TenantConstants.TENANT_ADMIN_ROLE_KEY
-    }, mode = SaMode.OR)
-    @SaCheckPermission("system:menu:query")
-    @GetMapping(value = "/roleMenuTreeselect/{roleId}")
-    public R<MenuTreeSelectVo> roleMenuTreeselect(@PathVariable("roleId") Long roleId) {
-        List<SysMenuVo> menus = menuService.selectMenuList(LoginHelper.getUserId());
-        MenuTreeSelectVo selectVo = new MenuTreeSelectVo();
-        selectVo.setCheckedKeys(menuService.selectMenuListByRoleId(roleId));
-        selectVo.setMenus(menuService.buildMenuTreeSelect(menus));
-        return R.ok(selectVo);
-    }
-
-    /**
-     * 鍔犺浇瀵瑰簲绉熸埛濂楅鑿滃崟鍒楄〃鏍�
-     *
-     * @param packageId 绉熸埛濂楅ID
-     */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
-    @SaCheckPermission("system:menu:query")
-    @GetMapping(value = "/tenantPackageMenuTreeselect/{packageId}")
-    public R<MenuTreeSelectVo> tenantPackageMenuTreeselect(@PathVariable("packageId") Long packageId) {
-        List<SysMenuVo> menus = menuService.selectMenuList(LoginHelper.getUserId());
-        MenuTreeSelectVo selectVo = new MenuTreeSelectVo();
-        selectVo.setCheckedKeys(menuService.selectMenuListByPackageId(packageId));
-        selectVo.setMenus(menuService.buildMenuTreeSelect(menus));
-        return R.ok(selectVo);
-    }
-
-    /**
-     * 鏂板鑿滃崟
-     */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
-    @SaCheckPermission("system:menu:add")
-    @Log(title = "鑿滃崟绠$悊", businessType = BusinessType.INSERT)
-    @PostMapping
-    public R<Void> add(@Validated @RequestBody SysMenuBo menu) {
-        if (!menuService.checkMenuNameUnique(menu)) {
-            return R.fail("鏂板鑿滃崟'" + menu.getMenuName() + "'澶辫触锛岃彍鍗曞悕绉板凡瀛樺湪");
-        } else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) {
-            return R.fail("鏂板鑿滃崟'" + menu.getMenuName() + "'澶辫触锛屽湴鍧�蹇呴』浠ttp(s)://寮�澶�");
-        }
-        return toAjax(menuService.insertMenu(menu));
-    }
-
-    /**
-     * 淇敼鑿滃崟
-     */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
-    @SaCheckPermission("system:menu:edit")
-    @Log(title = "鑿滃崟绠$悊", businessType = BusinessType.UPDATE)
-    @PutMapping
-    public R<Void> edit(@Validated @RequestBody SysMenuBo menu) {
-        if (!menuService.checkMenuNameUnique(menu)) {
-            return R.fail("淇敼鑿滃崟'" + menu.getMenuName() + "'澶辫触锛岃彍鍗曞悕绉板凡瀛樺湪");
-        } else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) {
-            return R.fail("淇敼鑿滃崟'" + menu.getMenuName() + "'澶辫触锛屽湴鍧�蹇呴』浠ttp(s)://寮�澶�");
-        } else if (menu.getMenuId().equals(menu.getParentId())) {
-            return R.fail("淇敼鑿滃崟'" + menu.getMenuName() + "'澶辫触锛屼笂绾ц彍鍗曚笉鑳介�夋嫨鑷繁");
-        }
-        return toAjax(menuService.updateMenu(menu));
-    }
-
-    /**
-     * 鍒犻櫎鑿滃崟
-     *
-     * @param menuId 鑿滃崟ID
-     */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
-    @SaCheckPermission("system:menu:remove")
-    @Log(title = "鑿滃崟绠$悊", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{menuId}")
-    public R<Void> remove(@PathVariable("menuId") Long menuId) {
-        if (menuService.hasChildByMenuId(menuId)) {
-            return R.warn("瀛樺湪瀛愯彍鍗�,涓嶅厑璁稿垹闄�");
-        }
-        if (menuService.checkMenuExistRole(menuId)) {
-            return R.warn("鑿滃崟宸插垎閰�,涓嶅厑璁稿垹闄�");
-        }
-        return toAjax(menuService.deleteMenuById(menuId));
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysNoticeController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysNoticeController.java
deleted file mode 100644
index 7eb3b34..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysNoticeController.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package com.ruoyi.system.controller.system;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import com.ruoyi.common.log.annotation.Log;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.log.enums.BusinessType;
-import com.ruoyi.system.domain.bo.SysNoticeBo;
-import com.ruoyi.system.domain.vo.SysNoticeVo;
-import com.ruoyi.system.service.ISysNoticeService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-/**
- * 鍏憡 淇℃伅鎿嶄綔澶勭悊
- *
- * @author Lion Li
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/system/notice")
-public class SysNoticeController extends BaseController {
-
-    private final ISysNoticeService noticeService;
-
-    /**
-     * 鑾峰彇閫氱煡鍏憡鍒楄〃
-     */
-    @SaCheckPermission("system:notice:list")
-    @GetMapping("/list")
-    public TableDataInfo<SysNoticeVo> list(SysNoticeBo notice, PageQuery pageQuery) {
-        return noticeService.selectPageNoticeList(notice, pageQuery);
-    }
-
-    /**
-     * 鏍规嵁閫氱煡鍏憡缂栧彿鑾峰彇璇︾粏淇℃伅
-     *
-     * @param noticeId 鍏憡ID
-     */
-    @SaCheckPermission("system:notice:query")
-    @GetMapping(value = "/{noticeId}")
-    public R<SysNoticeVo> getInfo(@PathVariable Long noticeId) {
-        return R.ok(noticeService.selectNoticeById(noticeId));
-    }
-
-    /**
-     * 鏂板閫氱煡鍏憡
-     */
-    @SaCheckPermission("system:notice:add")
-    @Log(title = "閫氱煡鍏憡", businessType = BusinessType.INSERT)
-    @PostMapping
-    public R<Void> add(@Validated @RequestBody SysNoticeBo notice) {
-        return toAjax(noticeService.insertNotice(notice));
-    }
-
-    /**
-     * 淇敼閫氱煡鍏憡
-     */
-    @SaCheckPermission("system:notice:edit")
-    @Log(title = "閫氱煡鍏憡", businessType = BusinessType.UPDATE)
-    @PutMapping
-    public R<Void> edit(@Validated @RequestBody SysNoticeBo notice) {
-        return toAjax(noticeService.updateNotice(notice));
-    }
-
-    /**
-     * 鍒犻櫎閫氱煡鍏憡
-     *
-     * @param noticeIds 鍏憡ID涓�
-     */
-    @SaCheckPermission("system:notice:remove")
-    @Log(title = "閫氱煡鍏憡", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{noticeIds}")
-    public R<Void> remove(@PathVariable Long[] noticeIds) {
-        return toAjax(noticeService.deleteNoticeByIds(noticeIds));
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysOssConfigController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysOssConfigController.java
deleted file mode 100644
index 070df3e..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysOssConfigController.java
+++ /dev/null
@@ -1,105 +0,0 @@
-package com.ruoyi.system.controller.system;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.core.validate.AddGroup;
-import com.ruoyi.common.core.validate.EditGroup;
-import com.ruoyi.common.core.validate.QueryGroup;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.common.idempotent.annotation.RepeatSubmit;
-import com.ruoyi.common.log.annotation.Log;
-import com.ruoyi.common.log.enums.BusinessType;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.system.domain.bo.SysOssConfigBo;
-import com.ruoyi.system.domain.vo.SysOssConfigVo;
-import com.ruoyi.system.service.ISysOssConfigService;
-import jakarta.validation.constraints.NotEmpty;
-import jakarta.validation.constraints.NotNull;
-import lombok.RequiredArgsConstructor;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-/**
- * 瀵硅薄瀛樺偍閰嶇疆
- *
- * @author Lion Li
- * @author 瀛よ垷鐑熼洦
- * @date 2021-08-13
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/system/oss/config")
-public class SysOssConfigController extends BaseController {
-
-    private final ISysOssConfigService ossConfigService;
-
-    /**
-     * 鏌ヨ瀵硅薄瀛樺偍閰嶇疆鍒楄〃
-     */
-    @SaCheckPermission("system:oss:list")
-    @GetMapping("/list")
-    public TableDataInfo<SysOssConfigVo> list(@Validated(QueryGroup.class) SysOssConfigBo bo, PageQuery pageQuery) {
-        return ossConfigService.queryPageList(bo, pageQuery);
-    }
-
-    /**
-     * 鑾峰彇瀵硅薄瀛樺偍閰嶇疆璇︾粏淇℃伅
-     *
-     * @param ossConfigId OSS閰嶇疆ID
-     */
-    @SaCheckPermission("system:oss:query")
-    @GetMapping("/{ossConfigId}")
-    public R<SysOssConfigVo> getInfo(@NotNull(message = "涓婚敭涓嶈兘涓虹┖")
-                                     @PathVariable Long ossConfigId) {
-        return R.ok(ossConfigService.queryById(ossConfigId));
-    }
-
-    /**
-     * 鏂板瀵硅薄瀛樺偍閰嶇疆
-     */
-    @SaCheckPermission("system:oss:add")
-    @Log(title = "瀵硅薄瀛樺偍閰嶇疆", businessType = BusinessType.INSERT)
-    @RepeatSubmit()
-    @PostMapping()
-    public R<Void> add(@Validated(AddGroup.class) @RequestBody SysOssConfigBo bo) {
-        return toAjax(ossConfigService.insertByBo(bo));
-    }
-
-    /**
-     * 淇敼瀵硅薄瀛樺偍閰嶇疆
-     */
-    @SaCheckPermission("system:oss:edit")
-    @Log(title = "瀵硅薄瀛樺偍閰嶇疆", businessType = BusinessType.UPDATE)
-    @RepeatSubmit()
-    @PutMapping()
-    public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysOssConfigBo bo) {
-        return toAjax(ossConfigService.updateByBo(bo));
-    }
-
-    /**
-     * 鍒犻櫎瀵硅薄瀛樺偍閰嶇疆
-     *
-     * @param ossConfigIds OSS閰嶇疆ID涓�
-     */
-    @SaCheckPermission("system:oss:remove")
-    @Log(title = "瀵硅薄瀛樺偍閰嶇疆", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{ossConfigIds}")
-    public R<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
-                          @PathVariable Long[] ossConfigIds) {
-        return toAjax(ossConfigService.deleteWithValidByIds(List.of(ossConfigIds), true));
-    }
-
-    /**
-     * 鐘舵�佷慨鏀�
-     */
-    @SaCheckPermission("system:oss:edit")
-    @Log(title = "瀵硅薄瀛樺偍鐘舵�佷慨鏀�", businessType = BusinessType.UPDATE)
-    @PutMapping("/changeStatus")
-    public R<Void> changeStatus(@RequestBody SysOssConfigBo bo) {
-        return toAjax(ossConfigService.updateOssConfigStatus(bo));
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysOssController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysOssController.java
deleted file mode 100644
index e7192b8..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysOssController.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package com.ruoyi.system.controller.system;
-
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import cn.hutool.core.util.ObjectUtil;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.validate.QueryGroup;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.common.log.annotation.Log;
-import com.ruoyi.common.log.enums.BusinessType;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.system.domain.bo.SysOssBo;
-import com.ruoyi.system.domain.vo.SysOssUploadVo;
-import com.ruoyi.system.domain.vo.SysOssVo;
-import com.ruoyi.system.service.ISysOssService;
-import jakarta.servlet.http.HttpServletResponse;
-import jakarta.validation.constraints.NotEmpty;
-import lombok.RequiredArgsConstructor;
-import org.springframework.http.MediaType;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * 鏂囦欢涓婁紶 鎺у埗灞�
- *
- * @author Lion Li
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/system/oss")
-public class SysOssController extends BaseController {
-
-    private final ISysOssService ossService;
-
-    /**
-     * 鏌ヨOSS瀵硅薄瀛樺偍鍒楄〃
-     */
-    @SaCheckPermission("system:oss:list")
-    @GetMapping("/list")
-    public TableDataInfo<SysOssVo> list(@Validated(QueryGroup.class) SysOssBo bo, PageQuery pageQuery) {
-        return ossService.queryPageList(bo, pageQuery);
-    }
-
-    /**
-     * 鏌ヨOSS瀵硅薄鍩轰簬id涓�
-     *
-     * @param ossIds OSS瀵硅薄ID涓�
-     */
-    @SaCheckPermission("system:oss:list")
-    @GetMapping("/listByIds/{ossIds}")
-    public R<List<SysOssVo>> listByIds(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
-                                       @PathVariable Long[] ossIds) {
-        List<SysOssVo> list = ossService.listByIds(Arrays.asList(ossIds));
-        return R.ok(list);
-    }
-
-    /**
-     * 涓婁紶OSS瀵硅薄瀛樺偍
-     *
-     * @param file 鏂囦欢
-     */
-    @SaCheckPermission("system:oss:upload")
-    @Log(title = "OSS瀵硅薄瀛樺偍", businessType = BusinessType.INSERT)
-    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
-    public R<SysOssUploadVo> upload(@RequestPart("file") MultipartFile file) {
-        if (ObjectUtil.isNull(file)) {
-            return R.fail("涓婁紶鏂囦欢涓嶈兘涓虹┖");
-        }
-        SysOssVo oss = ossService.upload(file);
-        SysOssUploadVo uploadVo = new SysOssUploadVo();
-        uploadVo.setUrl(oss.getUrl());
-        uploadVo.setFileName(oss.getOriginalName());
-        uploadVo.setOssId(oss.getOssId().toString());
-        return R.ok(uploadVo);
-    }
-
-    /**
-     * 涓嬭浇OSS瀵硅薄
-     *
-     * @param ossId OSS瀵硅薄ID
-     */
-    @SaCheckPermission("system:oss:download")
-    @GetMapping("/download/{ossId}")
-    public void download(@PathVariable Long ossId, HttpServletResponse response) throws IOException {
-        ossService.download(ossId, response);
-    }
-
-    /**
-     * 鍒犻櫎OSS瀵硅薄瀛樺偍
-     *
-     * @param ossIds OSS瀵硅薄ID涓�
-     */
-    @SaCheckPermission("system:oss:remove")
-    @Log(title = "OSS瀵硅薄瀛樺偍", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{ossIds}")
-    public R<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
-                          @PathVariable Long[] ossIds) {
-        return toAjax(ossService.deleteWithValidByIds(List.of(ossIds), true));
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysPostController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysPostController.java
deleted file mode 100644
index 88027a6..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysPostController.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package com.ruoyi.system.controller.system;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.excel.utils.ExcelUtil;
-import com.ruoyi.common.log.annotation.Log;
-import com.ruoyi.common.log.enums.BusinessType;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.system.domain.bo.SysPostBo;
-import com.ruoyi.system.domain.vo.SysPostVo;
-import com.ruoyi.system.service.ISysPostService;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.RequiredArgsConstructor;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-/**
- * 宀椾綅淇℃伅鎿嶄綔澶勭悊
- *
- * @author Lion Li
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/system/post")
-public class SysPostController extends BaseController {
-
-    private final ISysPostService postService;
-
-    /**
-     * 鑾峰彇宀椾綅鍒楄〃
-     */
-    @SaCheckPermission("system:post:list")
-    @GetMapping("/list")
-    public TableDataInfo<SysPostVo> list(SysPostBo post, PageQuery pageQuery) {
-        return postService.selectPagePostList(post, pageQuery);
-    }
-
-    /**
-     * 瀵煎嚭宀椾綅鍒楄〃
-     */
-    @Log(title = "宀椾綅绠$悊", businessType = BusinessType.EXPORT)
-    @SaCheckPermission("system:post:export")
-    @PostMapping("/export")
-    public void export(SysPostBo post, HttpServletResponse response) {
-        List<SysPostVo> list = postService.selectPostList(post);
-        ExcelUtil.exportExcel(list, "宀椾綅鏁版嵁", SysPostVo.class, response);
-    }
-
-    /**
-     * 鏍规嵁宀椾綅缂栧彿鑾峰彇璇︾粏淇℃伅
-     *
-     * @param postId 宀椾綅ID
-     */
-    @SaCheckPermission("system:post:query")
-    @GetMapping(value = "/{postId}")
-    public R<SysPostVo> getInfo(@PathVariable Long postId) {
-        return R.ok(postService.selectPostById(postId));
-    }
-
-    /**
-     * 鏂板宀椾綅
-     */
-    @SaCheckPermission("system:post:add")
-    @Log(title = "宀椾綅绠$悊", businessType = BusinessType.INSERT)
-    @PostMapping
-    public R<Void> add(@Validated @RequestBody SysPostBo post) {
-        if (!postService.checkPostNameUnique(post)) {
-            return R.fail("鏂板宀椾綅'" + post.getPostName() + "'澶辫触锛屽矖浣嶅悕绉板凡瀛樺湪");
-        } else if (!postService.checkPostCodeUnique(post)) {
-            return R.fail("鏂板宀椾綅'" + post.getPostName() + "'澶辫触锛屽矖浣嶇紪鐮佸凡瀛樺湪");
-        }
-        return toAjax(postService.insertPost(post));
-    }
-
-    /**
-     * 淇敼宀椾綅
-     */
-    @SaCheckPermission("system:post:edit")
-    @Log(title = "宀椾綅绠$悊", businessType = BusinessType.UPDATE)
-    @PutMapping
-    public R<Void> edit(@Validated @RequestBody SysPostBo post) {
-        if (!postService.checkPostNameUnique(post)) {
-            return R.fail("淇敼宀椾綅'" + post.getPostName() + "'澶辫触锛屽矖浣嶅悕绉板凡瀛樺湪");
-        } else if (!postService.checkPostCodeUnique(post)) {
-            return R.fail("淇敼宀椾綅'" + post.getPostName() + "'澶辫触锛屽矖浣嶇紪鐮佸凡瀛樺湪");
-        }
-        return toAjax(postService.updatePost(post));
-    }
-
-    /**
-     * 鍒犻櫎宀椾綅
-     *
-     * @param postIds 宀椾綅ID涓�
-     */
-    @SaCheckPermission("system:post:remove")
-    @Log(title = "宀椾綅绠$悊", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{postIds}")
-    public R<Void> remove(@PathVariable Long[] postIds) {
-        return toAjax(postService.deletePostByIds(postIds));
-    }
-
-    /**
-     * 鑾峰彇宀椾綅閫夋嫨妗嗗垪琛�
-     */
-    @GetMapping("/optionselect")
-    public R<List<SysPostVo>> optionselect() {
-        List<SysPostVo> posts = postService.selectPostAll();
-        return R.ok(posts);
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysProfileController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysProfileController.java
deleted file mode 100644
index 52f314d..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysProfileController.java
+++ /dev/null
@@ -1,123 +0,0 @@
-package com.ruoyi.system.controller.system;
-
-import cn.dev33.satoken.secure.BCrypt;
-import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.io.FileUtil;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.core.utils.file.MimeTypeUtils;
-import com.ruoyi.common.log.annotation.Log;
-import com.ruoyi.common.log.enums.BusinessType;
-import com.ruoyi.common.satoken.utils.LoginHelper;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.system.domain.bo.SysUserBo;
-import com.ruoyi.system.domain.bo.SysUserProfileBo;
-import com.ruoyi.system.domain.vo.AvatarVo;
-import com.ruoyi.system.domain.vo.ProfileVo;
-import com.ruoyi.system.domain.vo.SysOssVo;
-import com.ruoyi.system.domain.vo.SysUserVo;
-import com.ruoyi.system.service.ISysOssService;
-import com.ruoyi.system.service.ISysUserService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.http.MediaType;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.util.Arrays;
-
-/**
- * 涓汉淇℃伅 涓氬姟澶勭悊
- *
- * @author Lion Li
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/system/user/profile")
-public class SysProfileController extends BaseController {
-
-    private final ISysUserService userService;
-    private final ISysOssService ossService;
-
-    /**
-     * 涓汉淇℃伅
-     */
-    @GetMapping
-    public R<ProfileVo> profile() {
-        SysUserVo user = userService.selectUserById(LoginHelper.getUserId());
-        ProfileVo profileVo = new ProfileVo();
-        profileVo.setUser(user);
-        profileVo.setRoleGroup(userService.selectUserRoleGroup(user.getUserName()));
-        profileVo.setPostGroup(userService.selectUserPostGroup(user.getUserName()));
-        return R.ok(profileVo);
-    }
-
-    /**
-     * 淇敼鐢ㄦ埛
-     */
-    @Log(title = "涓汉淇℃伅", businessType = BusinessType.UPDATE)
-    @PutMapping
-    public R<Void> updateProfile(@RequestBody SysUserProfileBo profile) {
-        SysUserBo user = BeanUtil.toBean(profile, SysUserBo.class);
-        if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
-            return R.fail("淇敼鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛屾墜鏈哄彿鐮佸凡瀛樺湪");
-        }
-        if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
-            return R.fail("淇敼鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛岄偖绠辫处鍙峰凡瀛樺湪");
-        }
-        user.setUserId(LoginHelper.getUserId());
-        if (userService.updateUserProfile(user) > 0) {
-            return R.ok();
-        }
-        return R.fail("淇敼涓汉淇℃伅寮傚父锛岃鑱旂郴绠$悊鍛�");
-    }
-
-    /**
-     * 閲嶇疆瀵嗙爜
-     *
-     * @param newPassword 鏃у瘑鐮�
-     * @param oldPassword 鏂板瘑鐮�
-     */
-    @Log(title = "涓汉淇℃伅", businessType = BusinessType.UPDATE)
-    @PutMapping("/updatePwd")
-    public R<Void> updatePwd(String oldPassword, String newPassword) {
-        SysUserVo user = userService.selectUserById(LoginHelper.getUserId());
-        String password = user.getPassword();
-        if (!BCrypt.checkpw(oldPassword, password)) {
-            return R.fail("淇敼瀵嗙爜澶辫触锛屾棫瀵嗙爜閿欒");
-        }
-        if (BCrypt.checkpw(newPassword, password)) {
-            return R.fail("鏂板瘑鐮佷笉鑳戒笌鏃у瘑鐮佺浉鍚�");
-        }
-
-        if (userService.resetUserPwd(user.getUserId(), BCrypt.hashpw(newPassword)) > 0) {
-            return R.ok();
-        }
-        return R.fail("淇敼瀵嗙爜寮傚父锛岃鑱旂郴绠$悊鍛�");
-    }
-
-    /**
-     * 澶村儚涓婁紶
-     *
-     * @param avatarfile 鐢ㄦ埛澶村儚
-     */
-    @Log(title = "鐢ㄦ埛澶村儚", businessType = BusinessType.UPDATE)
-    @PostMapping(value = "/avatar", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
-    public R<AvatarVo> avatar(@RequestPart("avatarfile") MultipartFile avatarfile) {
-        if (!avatarfile.isEmpty()) {
-            String extension = FileUtil.extName(avatarfile.getOriginalFilename());
-            if (!StringUtils.equalsAnyIgnoreCase(extension, MimeTypeUtils.IMAGE_EXTENSION)) {
-                return R.fail("鏂囦欢鏍煎紡涓嶆纭紝璇蜂笂浼�" + Arrays.toString(MimeTypeUtils.IMAGE_EXTENSION) + "鏍煎紡");
-            }
-            SysOssVo oss = ossService.upload(avatarfile);
-            String avatar = oss.getUrl();
-            if (userService.updateUserAvatar(LoginHelper.getUserId(), oss.getOssId())) {
-                AvatarVo avatarVo = new AvatarVo();
-                avatarVo.setImgUrl(avatar);
-                return R.ok(avatarVo);
-            }
-        }
-        return R.fail("涓婁紶鍥剧墖寮傚父锛岃鑱旂郴绠$悊鍛�");
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysRoleController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysRoleController.java
deleted file mode 100644
index 4ef7c36..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysRoleController.java
+++ /dev/null
@@ -1,250 +0,0 @@
-package com.ruoyi.system.controller.system;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import cn.dev33.satoken.exception.NotLoginException;
-import cn.dev33.satoken.stp.StpUtil;
-import cn.hutool.core.collection.CollUtil;
-import com.ruoyi.common.core.constant.GlobalConstants;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.core.domain.model.LoginUser;
-import com.ruoyi.common.excel.utils.ExcelUtil;
-import com.ruoyi.common.log.annotation.Log;
-import com.ruoyi.common.log.enums.BusinessType;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.satoken.utils.LoginHelper;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.system.domain.SysUserRole;
-import com.ruoyi.system.domain.bo.SysDeptBo;
-import com.ruoyi.system.domain.bo.SysRoleBo;
-import com.ruoyi.system.domain.bo.SysUserBo;
-import com.ruoyi.system.domain.vo.DeptTreeSelectVo;
-import com.ruoyi.system.domain.vo.SysRoleVo;
-import com.ruoyi.system.domain.vo.SysUserVo;
-import com.ruoyi.system.service.ISysDeptService;
-import com.ruoyi.system.service.ISysRoleService;
-import com.ruoyi.system.service.ISysUserService;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.RequiredArgsConstructor;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-/**
- * 瑙掕壊淇℃伅
- *
- * @author Lion Li
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/system/role")
-public class SysRoleController extends BaseController {
-
-    private final ISysRoleService roleService;
-    private final ISysUserService userService;
-    private final ISysDeptService deptService;
-
-    /**
-     * 鑾峰彇瑙掕壊淇℃伅鍒楄〃
-     */
-    @SaCheckPermission("system:role:list")
-    @GetMapping("/list")
-    public TableDataInfo<SysRoleVo> list(SysRoleBo role, PageQuery pageQuery) {
-        return roleService.selectPageRoleList(role, pageQuery);
-    }
-
-    /**
-     * 瀵煎嚭瑙掕壊淇℃伅鍒楄〃
-     */
-    @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.EXPORT)
-    @SaCheckPermission("system:role:export")
-    @PostMapping("/export")
-    public void export(SysRoleBo role, HttpServletResponse response) {
-        List<SysRoleVo> list = roleService.selectRoleList(role);
-        ExcelUtil.exportExcel(list, "瑙掕壊鏁版嵁", SysRoleVo.class, response);
-    }
-
-    /**
-     * 鏍规嵁瑙掕壊缂栧彿鑾峰彇璇︾粏淇℃伅
-     *
-     * @param roleId 瑙掕壊ID
-     */
-    @SaCheckPermission("system:role:query")
-    @GetMapping(value = "/{roleId}")
-    public R<SysRoleVo> getInfo(@PathVariable Long roleId) {
-        roleService.checkRoleDataScope(roleId);
-        return R.ok(roleService.selectRoleById(roleId));
-    }
-
-    /**
-     * 鏂板瑙掕壊
-     */
-    @SaCheckPermission("system:role:add")
-    @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.INSERT)
-    @PostMapping
-    public R<Void> add(@Validated @RequestBody SysRoleBo role) {
-        if (!roleService.checkRoleNameUnique(role)) {
-            return R.fail("鏂板瑙掕壊'" + role.getRoleName() + "'澶辫触锛岃鑹插悕绉板凡瀛樺湪");
-        } else if (!roleService.checkRoleKeyUnique(role)) {
-            return R.fail("鏂板瑙掕壊'" + role.getRoleName() + "'澶辫触锛岃鑹叉潈闄愬凡瀛樺湪");
-        }
-        return toAjax(roleService.insertRole(role));
-
-    }
-
-    /**
-     * 淇敼淇濆瓨瑙掕壊
-     */
-    @SaCheckPermission("system:role:edit")
-    @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.UPDATE)
-    @PutMapping
-    public R<Void> edit(@Validated @RequestBody SysRoleBo role) {
-        roleService.checkRoleAllowed(role.getRoleId());
-        roleService.checkRoleDataScope(role.getRoleId());
-        if (!roleService.checkRoleNameUnique(role)) {
-            return R.fail("淇敼瑙掕壊'" + role.getRoleName() + "'澶辫触锛岃鑹插悕绉板凡瀛樺湪");
-        } else if (!roleService.checkRoleKeyUnique(role)) {
-            return R.fail("淇敼瑙掕壊'" + role.getRoleName() + "'澶辫触锛岃鑹叉潈闄愬凡瀛樺湪");
-        }
-
-        if (roleService.updateRole(role) > 0) {
-            List<String> keys = StpUtil.searchTokenValue("", 0, -1, false);
-            if (CollUtil.isEmpty(keys)) {
-                return R.ok();
-            }
-            // 瑙掕壊鍏宠仈鐨勫湪绾跨敤鎴烽噺杩囧ぇ浼氬鑷磖edis闃诲鍗¢】 璋ㄦ厧鎿嶄綔
-            keys.parallelStream().forEach(key -> {
-                String token = key.replace(GlobalConstants.LOGIN_TOKEN_KEY, "");
-                // 濡傛灉宸茬粡杩囨湡鍒欒烦杩�
-                if (StpUtil.stpLogic.getTokenActivityTimeoutByToken(token) < -1) {
-                    return;
-                }
-                LoginUser loginUser = LoginHelper.getLoginUser(token);
-                if (loginUser.getRoles().stream().anyMatch(r -> r.getRoleId().equals(role.getRoleId()))) {
-                    try {
-                        StpUtil.logoutByTokenValue(token);
-                    } catch (NotLoginException ignored) {
-                    }
-                }
-            });
-            return R.ok();
-        }
-        return R.fail("淇敼瑙掕壊'" + role.getRoleName() + "'澶辫触锛岃鑱旂郴绠$悊鍛�");
-    }
-
-    /**
-     * 淇敼淇濆瓨鏁版嵁鏉冮檺
-     */
-    @SaCheckPermission("system:role:edit")
-    @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.UPDATE)
-    @PutMapping("/dataScope")
-    public R<Void> dataScope(@RequestBody SysRoleBo role) {
-        roleService.checkRoleAllowed(role.getRoleId());
-        roleService.checkRoleDataScope(role.getRoleId());
-        return toAjax(roleService.authDataScope(role));
-    }
-
-    /**
-     * 鐘舵�佷慨鏀�
-     */
-    @SaCheckPermission("system:role:edit")
-    @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.UPDATE)
-    @PutMapping("/changeStatus")
-    public R<Void> changeStatus(@RequestBody SysRoleBo role) {
-        roleService.checkRoleAllowed(role.getRoleId());
-        roleService.checkRoleDataScope(role.getRoleId());
-        return toAjax(roleService.updateRoleStatus(role.getRoleId(), role.getStatus()));
-    }
-
-    /**
-     * 鍒犻櫎瑙掕壊
-     *
-     * @param roleIds 瑙掕壊ID涓�
-     */
-    @SaCheckPermission("system:role:remove")
-    @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{roleIds}")
-    public R<Void> remove(@PathVariable Long[] roleIds) {
-        return toAjax(roleService.deleteRoleByIds(roleIds));
-    }
-
-    /**
-     * 鑾峰彇瑙掕壊閫夋嫨妗嗗垪琛�
-     */
-    @SaCheckPermission("system:role:query")
-    @GetMapping("/optionselect")
-    public R<List<SysRoleVo>> optionselect() {
-        return R.ok(roleService.selectRoleAll());
-    }
-
-    /**
-     * 鏌ヨ宸插垎閰嶇敤鎴疯鑹插垪琛�
-     */
-    @SaCheckPermission("system:role:list")
-    @GetMapping("/authUser/allocatedList")
-    public TableDataInfo<SysUserVo> allocatedList(SysUserBo user, PageQuery pageQuery) {
-        return userService.selectAllocatedList(user, pageQuery);
-    }
-
-    /**
-     * 鏌ヨ鏈垎閰嶇敤鎴疯鑹插垪琛�
-     */
-    @SaCheckPermission("system:role:list")
-    @GetMapping("/authUser/unallocatedList")
-    public TableDataInfo<SysUserVo> unallocatedList(SysUserBo user, PageQuery pageQuery) {
-        return userService.selectUnallocatedList(user, pageQuery);
-    }
-
-    /**
-     * 鍙栨秷鎺堟潈鐢ㄦ埛
-     */
-    @SaCheckPermission("system:role:edit")
-    @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.GRANT)
-    @PutMapping("/authUser/cancel")
-    public R<Void> cancelAuthUser(@RequestBody SysUserRole userRole) {
-        return toAjax(roleService.deleteAuthUser(userRole));
-    }
-
-    /**
-     * 鎵归噺鍙栨秷鎺堟潈鐢ㄦ埛
-     *
-     * @param roleId  瑙掕壊ID
-     * @param userIds 鐢ㄦ埛ID涓�
-     */
-    @SaCheckPermission("system:role:edit")
-    @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.GRANT)
-    @PutMapping("/authUser/cancelAll")
-    public R<Void> cancelAuthUserAll(Long roleId, Long[] userIds) {
-        return toAjax(roleService.deleteAuthUsers(roleId, userIds));
-    }
-
-    /**
-     * 鎵归噺閫夋嫨鐢ㄦ埛鎺堟潈
-     *
-     * @param roleId  瑙掕壊ID
-     * @param userIds 鐢ㄦ埛ID涓�
-     */
-    @SaCheckPermission("system:role:edit")
-    @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.GRANT)
-    @PutMapping("/authUser/selectAll")
-    public R<Void> selectAuthUserAll(Long roleId, Long[] userIds) {
-        roleService.checkRoleDataScope(roleId);
-        return toAjax(roleService.insertAuthUsers(roleId, userIds));
-    }
-
-    /**
-     * 鑾峰彇瀵瑰簲瑙掕壊閮ㄩ棬鏍戝垪琛�
-     *
-     * @param roleId 瑙掕壊ID
-     */
-    @SaCheckPermission("system:role:list")
-    @GetMapping(value = "/deptTree/{roleId}")
-    public R<DeptTreeSelectVo> roleDeptTreeselect(@PathVariable("roleId") Long roleId) {
-        DeptTreeSelectVo selectVo = new DeptTreeSelectVo();
-        selectVo.setCheckedKeys(deptService.selectDeptListByRoleId(roleId));
-        selectVo.setDepts(deptService.selectDeptTreeList(new SysDeptBo()));
-        return R.ok(selectVo);
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysTenantController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysTenantController.java
deleted file mode 100644
index 5b264bd..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysTenantController.java
+++ /dev/null
@@ -1,176 +0,0 @@
-package com.ruoyi.system.controller.system;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import cn.dev33.satoken.annotation.SaCheckRole;
-import com.baomidou.lock.annotation.Lock4j;
-import com.ruoyi.common.core.constant.TenantConstants;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.validate.AddGroup;
-import com.ruoyi.common.core.validate.EditGroup;
-import com.ruoyi.common.excel.utils.ExcelUtil;
-import com.ruoyi.common.idempotent.annotation.RepeatSubmit;
-import com.ruoyi.common.log.annotation.Log;
-import com.ruoyi.common.log.enums.BusinessType;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.tenant.helper.TenantHelper;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.system.domain.bo.SysTenantBo;
-import com.ruoyi.system.domain.vo.SysTenantVo;
-import com.ruoyi.system.service.ISysTenantService;
-import com.ruoyi.system.service.ISysUserService;
-import jakarta.servlet.http.HttpServletResponse;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotEmpty;
-import jakarta.validation.constraints.NotNull;
-import lombok.RequiredArgsConstructor;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-/**
- * 绉熸埛绠$悊
- *
- * @author Michelle.Chung
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/system/tenant")
-public class SysTenantController extends BaseController {
-
-    private final ISysTenantService tenantService;
-
-    /**
-     * 鏌ヨ绉熸埛鍒楄〃
-     */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
-    @SaCheckPermission("system:tenant:list")
-    @GetMapping("/list")
-    public TableDataInfo<SysTenantVo> list(SysTenantBo bo, PageQuery pageQuery) {
-        return tenantService.queryPageList(bo, pageQuery);
-    }
-
-    /**
-     * 瀵煎嚭绉熸埛鍒楄〃
-     */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
-    @SaCheckPermission("system:tenant:export")
-    @Log(title = "绉熸埛", businessType = BusinessType.EXPORT)
-    @PostMapping("/export")
-    public void export(SysTenantBo bo, HttpServletResponse response) {
-        List<SysTenantVo> list = tenantService.queryList(bo);
-        ExcelUtil.exportExcel(list, "绉熸埛", SysTenantVo.class, response);
-    }
-
-    /**
-     * 鑾峰彇绉熸埛璇︾粏淇℃伅
-     *
-     * @param id 涓婚敭
-     */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
-    @SaCheckPermission("system:tenant:query")
-    @GetMapping("/{id}")
-    public R<SysTenantVo> getInfo(@NotNull(message = "涓婚敭涓嶈兘涓虹┖")
-                                     @PathVariable Long id) {
-        return R.ok(tenantService.queryById(id));
-    }
-
-    /**
-     * 鏂板绉熸埛
-     */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
-    @SaCheckPermission("system:tenant:add")
-    @Log(title = "绉熸埛", businessType = BusinessType.INSERT)
-    @Lock4j
-    @RepeatSubmit()
-    @PostMapping()
-    public R<Void> add(@Validated(AddGroup.class) @RequestBody SysTenantBo bo) {
-        if (!tenantService.checkCompanyNameUnique(bo)) {
-            return R.fail("鏂板绉熸埛'" + bo.getCompanyName() + "'澶辫触锛屼紒涓氬悕绉板凡瀛樺湪");
-        }
-        return toAjax(tenantService.insertByBo(bo));
-    }
-
-    /**
-     * 淇敼绉熸埛
-     */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
-    @SaCheckPermission("system:tenant:edit")
-    @Log(title = "绉熸埛", businessType = BusinessType.UPDATE)
-    @RepeatSubmit()
-    @PutMapping()
-    public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysTenantBo bo) {
-        tenantService.checkTenantAllowed(bo.getTenantId());
-        if (!tenantService.checkCompanyNameUnique(bo)) {
-            return R.fail("淇敼绉熸埛'" + bo.getCompanyName() + "'澶辫触锛屽叕鍙稿悕绉板凡瀛樺湪");
-        }
-        return toAjax(tenantService.updateByBo(bo));
-    }
-
-    /**
-     * 鐘舵�佷慨鏀�
-     */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
-    @SaCheckPermission("system:tenant:edit")
-    @Log(title = "绉熸埛", businessType = BusinessType.UPDATE)
-    @PutMapping("/changeStatus")
-    public R<Void> changeStatus(@RequestBody SysTenantBo bo) {
-        tenantService.checkTenantAllowed(bo.getTenantId());
-        return toAjax(tenantService.updateTenantStatus(bo));
-    }
-
-    /**
-     * 鍒犻櫎绉熸埛
-     *
-     * @param ids 涓婚敭涓�
-     */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
-    @SaCheckPermission("system:tenant:remove")
-    @Log(title = "绉熸埛", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{ids}")
-    public R<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
-                          @PathVariable Long[] ids) {
-        return toAjax(tenantService.deleteWithValidByIds(List.of(ids), true));
-    }
-
-    /**
-     * 鍔ㄦ�佸垏鎹㈢鎴�
-     *
-     * @param tenantId 绉熸埛ID
-     */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
-    @GetMapping("/dynamic/{tenantId}")
-    public R<Void> dynamicTenant(@NotBlank(message = "绉熸埛ID涓嶈兘涓虹┖") @PathVariable String tenantId) {
-        TenantHelper.setDynamic(tenantId);
-        return R.ok();
-    }
-
-    /**
-     * 娓呴櫎鍔ㄦ�佺鎴�
-     */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
-    @GetMapping("/dynamic/clear")
-    public R<Void> dynamicClear() {
-        TenantHelper.clearDynamic();
-        return R.ok();
-    }
-
-
-    /**
-     * 鍚屾绉熸埛濂楅
-     *
-     * @param tenantId  绉熸埛id
-     * @param packageId 濂楅id
-     */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
-    @SaCheckPermission("system:tenant:edit")
-    @Log(title = "绉熸埛", businessType = BusinessType.UPDATE)
-    @GetMapping("/syncTenantPackage")
-    public R<Void> syncTenantPackage(@NotBlank(message = "绉熸埛ID涓嶈兘涓虹┖") String tenantId, @NotBlank(message = "濂楅ID涓嶈兘涓虹┖") String packageId) {
-        return toAjax(tenantService.syncTenantPackage(tenantId, packageId));
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysTenantPackageController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysTenantPackageController.java
deleted file mode 100644
index 30f8d30..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysTenantPackageController.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package com.ruoyi.system.controller.system;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import cn.dev33.satoken.annotation.SaCheckRole;
-import com.ruoyi.common.core.constant.TenantConstants;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.core.validate.AddGroup;
-import com.ruoyi.common.core.validate.EditGroup;
-import com.ruoyi.common.excel.utils.ExcelUtil;
-import com.ruoyi.common.idempotent.annotation.RepeatSubmit;
-import com.ruoyi.common.log.annotation.Log;
-import com.ruoyi.common.log.enums.BusinessType;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.system.domain.bo.SysTenantPackageBo;
-import com.ruoyi.system.domain.vo.SysTenantPackageVo;
-import com.ruoyi.system.service.ISysTenantPackageService;
-import jakarta.servlet.http.HttpServletResponse;
-import jakarta.validation.constraints.NotEmpty;
-import jakarta.validation.constraints.NotNull;
-import lombok.RequiredArgsConstructor;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-/**
- * 绉熸埛濂楅绠$悊
- *
- * @author Michelle.Chung
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/system/tenant/package")
-public class SysTenantPackageController extends BaseController {
-
-    private final ISysTenantPackageService tenantPackageService;
-
-    /**
-     * 鏌ヨ绉熸埛濂楅鍒楄〃
-     */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
-    @SaCheckPermission("system:tenantPackage:list")
-    @GetMapping("/list")
-    public TableDataInfo<SysTenantPackageVo> list(SysTenantPackageBo bo, PageQuery pageQuery) {
-        return tenantPackageService.queryPageList(bo, pageQuery);
-    }
-
-    /**
-     * 瀵煎嚭绉熸埛濂楅鍒楄〃
-     */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
-    @SaCheckPermission("system:tenantPackage:export")
-    @Log(title = "绉熸埛濂楅", businessType = BusinessType.EXPORT)
-    @PostMapping("/export")
-    public void export(SysTenantPackageBo bo, HttpServletResponse response) {
-        List<SysTenantPackageVo> list = tenantPackageService.queryList(bo);
-        ExcelUtil.exportExcel(list, "绉熸埛濂楅", SysTenantPackageVo.class, response);
-    }
-
-    /**
-     * 鑾峰彇绉熸埛濂楅璇︾粏淇℃伅
-     *
-     * @param packageId 涓婚敭
-     */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
-    @SaCheckPermission("system:tenantPackage:query")
-    @GetMapping("/{packageId}")
-    public R<SysTenantPackageVo> getInfo(@NotNull(message = "涓婚敭涓嶈兘涓虹┖")
-                                     @PathVariable Long packageId) {
-        return R.ok(tenantPackageService.queryById(packageId));
-    }
-
-    /**
-     * 鏂板绉熸埛濂楅
-     */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
-    @SaCheckPermission("system:tenantPackage:add")
-    @Log(title = "绉熸埛濂楅", businessType = BusinessType.INSERT)
-    @RepeatSubmit()
-    @PostMapping()
-    public R<Void> add(@Validated(AddGroup.class) @RequestBody SysTenantPackageBo bo) {
-        return toAjax(tenantPackageService.insertByBo(bo));
-    }
-
-    /**
-     * 淇敼绉熸埛濂楅
-     */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
-    @SaCheckPermission("system:tenantPackage:edit")
-    @Log(title = "绉熸埛濂楅", businessType = BusinessType.UPDATE)
-    @RepeatSubmit()
-    @PutMapping()
-    public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysTenantPackageBo bo) {
-        return toAjax(tenantPackageService.updateByBo(bo));
-    }
-
-    /**
-     * 鐘舵�佷慨鏀�
-     */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
-    @SaCheckPermission("system:tenantPackage:edit")
-    @Log(title = "绉熸埛濂楅", businessType = BusinessType.UPDATE)
-    @PutMapping("/changeStatus")
-    public R<Void> changeStatus(@RequestBody SysTenantPackageBo bo) {
-        return toAjax(tenantPackageService.updatePackageStatus(bo));
-    }
-
-    /**
-     * 鍒犻櫎绉熸埛濂楅
-     *
-     * @param packageIds 涓婚敭涓�
-     */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
-    @SaCheckPermission("system:tenantPackage:remove")
-    @Log(title = "绉熸埛濂楅", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{packageIds}")
-    public R<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
-                          @PathVariable Long[] packageIds) {
-        return toAjax(tenantPackageService.deleteWithValidByIds(List.of(packageIds), true));
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysUserController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysUserController.java
deleted file mode 100644
index 67ac177..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysUserController.java
+++ /dev/null
@@ -1,261 +0,0 @@
-package com.ruoyi.system.controller.system;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import cn.dev33.satoken.secure.BCrypt;
-import cn.hutool.core.lang.tree.Tree;
-import cn.hutool.core.util.ArrayUtil;
-import cn.hutool.core.util.ObjectUtil;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.core.domain.model.LoginUser;
-import com.ruoyi.common.core.utils.MapstructUtils;
-import com.ruoyi.common.core.utils.StreamUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.excel.core.ExcelResult;
-import com.ruoyi.common.excel.utils.ExcelUtil;
-import com.ruoyi.common.log.annotation.Log;
-import com.ruoyi.common.log.enums.BusinessType;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.satoken.utils.LoginHelper;
-import com.ruoyi.common.tenant.helper.TenantHelper;
-import com.ruoyi.common.web.core.BaseController;
-import com.ruoyi.system.domain.bo.SysDeptBo;
-import com.ruoyi.system.domain.bo.SysUserBo;
-import com.ruoyi.system.domain.vo.*;
-import com.ruoyi.system.listener.SysUserImportListener;
-import com.ruoyi.system.service.*;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.RequiredArgsConstructor;
-import org.springframework.http.MediaType;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * 鐢ㄦ埛淇℃伅
- *
- * @author Lion Li
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/system/user")
-public class SysUserController extends BaseController {
-
-    private final ISysUserService userService;
-    private final ISysRoleService roleService;
-    private final ISysPostService postService;
-    private final ISysDeptService deptService;
-    private final ISysTenantService tenantService;
-
-    /**
-     * 鑾峰彇鐢ㄦ埛鍒楄〃
-     */
-    @SaCheckPermission("system:user:list")
-    @GetMapping("/list")
-    public TableDataInfo<SysUserVo> list(SysUserBo user, PageQuery pageQuery) {
-        return userService.selectPageUserList(user, pageQuery);
-    }
-
-    /**
-     * 瀵煎嚭鐢ㄦ埛鍒楄〃
-     */
-    @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.EXPORT)
-    @SaCheckPermission("system:user:export")
-    @PostMapping("/export")
-    public void export(SysUserBo user, HttpServletResponse response) {
-        List<SysUserVo> list = userService.selectUserList(user);
-        List<SysUserExportVo> listVo = MapstructUtils.convert(list, SysUserExportVo.class);
-        ExcelUtil.exportExcel(listVo, "鐢ㄦ埛鏁版嵁", SysUserExportVo.class, response);
-    }
-
-    /**
-     * 瀵煎叆鏁版嵁
-     *
-     * @param file          瀵煎叆鏂囦欢
-     * @param updateSupport 鏄惁鏇存柊宸插瓨鍦ㄦ暟鎹�
-     */
-    @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.IMPORT)
-    @SaCheckPermission("system:user:import")
-    @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
-    public R<Void> importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception {
-        ExcelResult<SysUserImportVo> result = ExcelUtil.importExcel(file.getInputStream(), SysUserImportVo.class, new SysUserImportListener(updateSupport));
-        return R.ok(result.getAnalysis());
-    }
-
-    /**
-     * 鑾峰彇瀵煎叆妯℃澘
-     */
-    @PostMapping("/importTemplate")
-    public void importTemplate(HttpServletResponse response) {
-        ExcelUtil.exportExcel(new ArrayList<>(), "鐢ㄦ埛鏁版嵁", SysUserImportVo.class, response);
-    }
-
-    /**
-     * 鑾峰彇鐢ㄦ埛淇℃伅
-     *
-     * @return 鐢ㄦ埛淇℃伅
-     */
-    @GetMapping("/getInfo")
-    public R<UserInfoVo> getInfo() {
-        UserInfoVo userInfoVo = new UserInfoVo();
-        LoginUser loginUser = LoginHelper.getLoginUser();
-        if (TenantHelper.isEnable() && LoginHelper.isSuperAdmin()) {
-            // 瓒呯骇绠$悊鍛� 濡傛灉閲嶆柊鍔犺浇鐢ㄦ埛淇℃伅闇�娓呴櫎鍔ㄦ�佺鎴�
-            TenantHelper.clearDynamic();
-        }
-        SysUserVo user = userService.selectUserById(loginUser.getUserId());
-        userInfoVo.setUser(user);
-        userInfoVo.setPermissions(loginUser.getMenuPermission());
-        userInfoVo.setRoles(loginUser.getRolePermission());
-        return R.ok(userInfoVo);
-    }
-
-    /**
-     * 鏍规嵁鐢ㄦ埛缂栧彿鑾峰彇璇︾粏淇℃伅
-     *
-     * @param userId 鐢ㄦ埛ID
-     */
-    @SaCheckPermission("system:user:query")
-    @GetMapping(value = {"/", "/{userId}"})
-    public R<SysUserInfoVo> getInfo(@PathVariable(value = "userId", required = false) Long userId) {
-        userService.checkUserDataScope(userId);
-        SysUserInfoVo userInfoVo = new SysUserInfoVo();
-        List<SysRoleVo> roles = roleService.selectRoleAll();
-        userInfoVo.setRoles(LoginHelper.isSuperAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isSuperAdmin()));
-        userInfoVo.setPosts(postService.selectPostAll());
-        if (ObjectUtil.isNotNull(userId)) {
-            SysUserVo sysUser = userService.selectUserById(userId);
-            userInfoVo.setUser(sysUser);
-            userInfoVo.setRoleIds(StreamUtils.toList(sysUser.getRoles(), SysRoleVo::getRoleId));
-            userInfoVo.setPostIds(postService.selectPostListByUserId(userId));
-        }
-        return R.ok(userInfoVo);
-    }
-
-    /**
-     * 鏂板鐢ㄦ埛
-     */
-    @SaCheckPermission("system:user:add")
-    @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.INSERT)
-    @PostMapping
-    public R<Void> add(@Validated @RequestBody SysUserBo user) {
-        if (!userService.checkUserNameUnique(user)) {
-            return R.fail("鏂板鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛岀櫥褰曡处鍙峰凡瀛樺湪");
-        } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
-            return R.fail("鏂板鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛屾墜鏈哄彿鐮佸凡瀛樺湪");
-        } else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
-            return R.fail("鏂板鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛岄偖绠辫处鍙峰凡瀛樺湪");
-        }
-        if (TenantHelper.isEnable()) {
-            if (!tenantService.checkAccountBalance(TenantHelper.getTenantId())) {
-                return R.fail("褰撳墠绉熸埛涓嬬敤鎴峰悕棰濅笉瓒筹紝璇疯仈绯荤鐞嗗憳");
-            }
-        }
-        user.setPassword(BCrypt.hashpw(user.getPassword()));
-        return toAjax(userService.insertUser(user));
-    }
-
-    /**
-     * 淇敼鐢ㄦ埛
-     */
-    @SaCheckPermission("system:user:edit")
-    @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.UPDATE)
-    @PutMapping
-    public R<Void> edit(@Validated @RequestBody SysUserBo user) {
-        userService.checkUserAllowed(user.getUserId());
-        userService.checkUserDataScope(user.getUserId());
-        if (!userService.checkUserNameUnique(user)) {
-            return R.fail("淇敼鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛岀櫥褰曡处鍙峰凡瀛樺湪");
-        } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
-            return R.fail("淇敼鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛屾墜鏈哄彿鐮佸凡瀛樺湪");
-        } else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
-            return R.fail("淇敼鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛岄偖绠辫处鍙峰凡瀛樺湪");
-        }
-        return toAjax(userService.updateUser(user));
-    }
-
-    /**
-     * 鍒犻櫎鐢ㄦ埛
-     *
-     * @param userIds 瑙掕壊ID涓�
-     */
-    @SaCheckPermission("system:user:remove")
-    @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{userIds}")
-    public R<Void> remove(@PathVariable Long[] userIds) {
-        if (ArrayUtil.contains(userIds, LoginHelper.getUserId())) {
-            return R.fail("褰撳墠鐢ㄦ埛涓嶈兘鍒犻櫎");
-        }
-        return toAjax(userService.deleteUserByIds(userIds));
-    }
-
-    /**
-     * 閲嶇疆瀵嗙爜
-     */
-    @SaCheckPermission("system:user:resetPwd")
-    @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.UPDATE)
-    @PutMapping("/resetPwd")
-    public R<Void> resetPwd(@RequestBody SysUserBo user) {
-        userService.checkUserAllowed(user.getUserId());
-        userService.checkUserDataScope(user.getUserId());
-        user.setPassword(BCrypt.hashpw(user.getPassword()));
-        return toAjax(userService.resetUserPwd(user.getUserId(), user.getPassword()));
-    }
-
-    /**
-     * 鐘舵�佷慨鏀�
-     */
-    @SaCheckPermission("system:user:edit")
-    @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.UPDATE)
-    @PutMapping("/changeStatus")
-    public R<Void> changeStatus(@RequestBody SysUserBo user) {
-        userService.checkUserAllowed(user.getUserId());
-        userService.checkUserDataScope(user.getUserId());
-        return toAjax(userService.updateUserStatus(user.getUserId(), user.getStatus()));
-    }
-
-    /**
-     * 鏍规嵁鐢ㄦ埛缂栧彿鑾峰彇鎺堟潈瑙掕壊
-     *
-     * @param userId 鐢ㄦ埛ID
-     */
-    @SaCheckPermission("system:user:query")
-    @GetMapping("/authRole/{userId}")
-    public R<SysUserInfoVo> authRole(@PathVariable Long userId) {
-        SysUserVo user = userService.selectUserById(userId);
-        List<SysRoleVo> roles = roleService.selectRolesByUserId(userId);
-        SysUserInfoVo userInfoVo = new SysUserInfoVo();
-        userInfoVo.setUser(user);
-        userInfoVo.setRoles(LoginHelper.isSuperAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isSuperAdmin()));
-        return R.ok(userInfoVo);
-    }
-
-    /**
-     * 鐢ㄦ埛鎺堟潈瑙掕壊
-     *
-     * @param userId  鐢ㄦ埛Id
-     * @param roleIds 瑙掕壊ID涓�
-     */
-    @SaCheckPermission("system:user:edit")
-    @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.GRANT)
-    @PutMapping("/authRole")
-    public R<Void> insertAuthRole(Long userId, Long[] roleIds) {
-        userService.checkUserDataScope(userId);
-        userService.insertUserAuth(userId, roleIds);
-        return R.ok();
-    }
-
-    /**
-     * 鑾峰彇閮ㄩ棬鏍戝垪琛�
-     */
-    @SaCheckPermission("system:user:list")
-    @GetMapping("/deptTree")
-    public R<List<Tree<Long>>> deptTree(SysDeptBo dept) {
-        return R.ok(deptService.selectDeptTreeList(dept));
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysCache.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysCache.java
deleted file mode 100644
index ac4e0af..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysCache.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.ruoyi.system.domain;
-
-import com.ruoyi.common.core.utils.StringUtils;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-/**
- * 缂撳瓨淇℃伅
- *
- * @author Lion Li
- */
-@Data
-@NoArgsConstructor
-public class SysCache {
-
-    /**
-     * 缂撳瓨鍚嶇О
-     */
-    private String cacheName = "";
-
-    /**
-     * 缂撳瓨閿悕
-     */
-    private String cacheKey = "";
-
-    /**
-     * 缂撳瓨鍐呭
-     */
-    private String cacheValue = "";
-
-    /**
-     * 澶囨敞
-     */
-    private String remark = "";
-
-    public SysCache(String cacheName, String remark) {
-        this.cacheName = cacheName;
-        this.remark = remark;
-    }
-
-    public SysCache(String cacheName, String cacheKey, String cacheValue) {
-        this.cacheName = StringUtils.replace(cacheName, ":", "");
-        this.cacheKey = StringUtils.replace(cacheKey, cacheName, "");
-        this.cacheValue = cacheValue;
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysConfig.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysConfig.java
deleted file mode 100644
index 3e62171..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysConfig.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.ruoyi.system.domain;
-
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.ruoyi.common.tenant.core.TenantEntity;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * 鍙傛暟閰嶇疆琛� sys_config
- *
- * @author Lion Li
- */
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("sys_config")
-public class SysConfig extends TenantEntity {
-
-    /**
-     * 鍙傛暟涓婚敭
-     */
-    @TableId(value = "config_id")
-    private Long configId;
-
-    /**
-     * 鍙傛暟鍚嶇О
-     */
-    private String configName;
-
-    /**
-     * 鍙傛暟閿悕
-     */
-    private String configKey;
-
-    /**
-     * 鍙傛暟閿��
-     */
-    private String configValue;
-
-    /**
-     * 绯荤粺鍐呯疆锛圷鏄� N鍚︼級
-     */
-    private String configType;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysDept.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysDept.java
deleted file mode 100644
index efa67ff..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysDept.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package com.ruoyi.system.domain;
-
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableLogic;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.ruoyi.common.tenant.core.TenantEntity;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import java.io.Serial;
-
-/**
- * 閮ㄩ棬琛� sys_dept
- *
- * @author Lion Li
- */
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("sys_dept")
-public class SysDept extends TenantEntity {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 閮ㄩ棬ID
-     */
-    @TableId(value = "dept_id")
-    private Long deptId;
-
-    /**
-     * 鐖堕儴闂↖D
-     */
-    private Long parentId;
-
-    /**
-     * 閮ㄩ棬鍚嶇О
-     */
-    private String deptName;
-
-    /**
-     * 鏄剧ず椤哄簭
-     */
-    private Integer orderNum;
-
-    /**
-     * 璐熻矗浜�
-     */
-    private String leader;
-
-    /**
-     * 鑱旂郴鐢佃瘽
-     */
-    private String phone;
-
-    /**
-     * 閭
-     */
-    private String email;
-
-    /**
-     * 閮ㄩ棬鐘舵��:0姝e父,1鍋滅敤
-     */
-    private String status;
-
-    /**
-     * 鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛�
-     */
-    @TableLogic
-    private String delFlag;
-
-    /**
-     * 绁栫骇鍒楄〃
-     */
-    private String ancestors;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysDictData.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysDictData.java
deleted file mode 100644
index ece40e3..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysDictData.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package com.ruoyi.system.domain;
-
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.ruoyi.common.core.constant.UserConstants;
-import com.ruoyi.common.tenant.core.TenantEntity;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * 瀛楀吀鏁版嵁琛� sys_dict_data
- *
- * @author Lion Li
- */
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("sys_dict_data")
-public class SysDictData extends TenantEntity {
-
-    /**
-     * 瀛楀吀缂栫爜
-     */
-    @TableId(value = "dict_code")
-    private Long dictCode;
-
-    /**
-     * 瀛楀吀鎺掑簭
-     */
-    private Integer dictSort;
-
-    /**
-     * 瀛楀吀鏍囩
-     */
-    private String dictLabel;
-
-    /**
-     * 瀛楀吀閿��
-     */
-    private String dictValue;
-
-    /**
-     * 瀛楀吀绫诲瀷
-     */
-    private String dictType;
-
-    /**
-     * 鏍峰紡灞炴�э紙鍏朵粬鏍峰紡鎵╁睍锛�
-     */
-    private String cssClass;
-
-    /**
-     * 琛ㄦ牸瀛楀吀鏍峰紡
-     */
-    private String listClass;
-
-    /**
-     * 鏄惁榛樿锛圷鏄� N鍚︼級
-     */
-    private String isDefault;
-
-    /**
-     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    private String status;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-    public boolean getDefault() {
-        return UserConstants.YES.equals(this.isDefault);
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysDictType.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysDictType.java
deleted file mode 100644
index 96a1f28..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysDictType.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package com.ruoyi.system.domain;
-
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.ruoyi.common.tenant.core.TenantEntity;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * 瀛楀吀绫诲瀷琛� sys_dict_type
- *
- * @author Lion Li
- */
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("sys_dict_type")
-public class SysDictType extends TenantEntity {
-
-    /**
-     * 瀛楀吀涓婚敭
-     */
-    @TableId(value = "dict_id")
-    private Long dictId;
-
-    /**
-     * 瀛楀吀鍚嶇О
-     */
-    private String dictName;
-
-    /**
-     * 瀛楀吀绫诲瀷
-     */
-    private String dictType;
-
-    /**
-     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    private String status;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysLogininfor.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysLogininfor.java
deleted file mode 100644
index 9ee8e62..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysLogininfor.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package com.ruoyi.system.domain;
-
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-
-/**
- * 绯荤粺璁块棶璁板綍琛� sys_logininfor
- *
- * @author Lion Li
- */
-
-@Data
-@TableName("sys_logininfor")
-public class SysLogininfor implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * ID
-     */
-    @TableId(value = "info_id")
-    private Long infoId;
-
-    /**
-     * 绉熸埛缂栧彿
-     */
-    private String tenantId;
-
-    /**
-     * 鐢ㄦ埛璐﹀彿
-     */
-    private String userName;
-
-    /**
-     * 鐧诲綍鐘舵�� 0鎴愬姛 1澶辫触
-     */
-    private String status;
-
-    /**
-     * 鐧诲綍IP鍦板潃
-     */
-    private String ipaddr;
-
-    /**
-     * 鐧诲綍鍦扮偣
-     */
-    private String loginLocation;
-
-    /**
-     * 娴忚鍣ㄧ被鍨�
-     */
-    private String browser;
-
-    /**
-     * 鎿嶄綔绯荤粺
-     */
-    private String os;
-
-    /**
-     * 鎻愮ず娑堟伅
-     */
-    private String msg;
-
-    /**
-     * 璁块棶鏃堕棿
-     */
-    private Date loginTime;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysMenu.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysMenu.java
deleted file mode 100644
index b02d74f..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysMenu.java
+++ /dev/null
@@ -1,191 +0,0 @@
-package com.ruoyi.system.domain;
-
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.ruoyi.common.core.constant.Constants;
-import com.ruoyi.common.core.constant.UserConstants;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * 鑿滃崟鏉冮檺琛� sys_menu
- *
- * @author Lion Li
- */
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("sys_menu")
-public class SysMenu extends BaseEntity {
-
-    /**
-     * 鑿滃崟ID
-     */
-    @TableId(value = "menu_id")
-    private Long menuId;
-
-    /**
-     * 鐖惰彍鍗旾D
-     */
-    private Long parentId;
-
-    /**
-     * 鑿滃崟鍚嶇О
-     */
-    private String menuName;
-
-    /**
-     * 鏄剧ず椤哄簭
-     */
-    private Integer orderNum;
-
-    /**
-     * 璺敱鍦板潃
-     */
-    private String path;
-
-    /**
-     * 缁勪欢璺緞
-     */
-    private String component;
-
-    /**
-     * 璺敱鍙傛暟
-     */
-    private String queryParam;
-
-    /**
-     * 鏄惁涓哄閾撅紙0鏄� 1鍚︼級
-     */
-    private String isFrame;
-
-    /**
-     * 鏄惁缂撳瓨锛�0缂撳瓨 1涓嶇紦瀛橈級
-     */
-    private String isCache;
-
-    /**
-     * 绫诲瀷锛圡鐩綍 C鑿滃崟 F鎸夐挳锛�
-     */
-    private String menuType;
-
-    /**
-     * 鏄剧ず鐘舵�侊紙0鏄剧ず 1闅愯棌锛�
-     */
-    private String visible;
-
-    /**
-     * 鑿滃崟鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    private String status;
-
-    /**
-     * 鏉冮檺瀛楃涓�
-     */
-    private String perms;
-
-    /**
-     * 鑿滃崟鍥炬爣
-     */
-    private String icon;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-    /**
-     * 鐖惰彍鍗曞悕绉�
-     */
-    @TableField(exist = false)
-    private String parentName;
-
-    /**
-     * 瀛愯彍鍗�
-     */
-    @TableField(exist = false)
-    private List<SysMenu> children = new ArrayList<>();
-
-    /**
-     * 鑾峰彇璺敱鍚嶇О
-     */
-    public String getRouteName() {
-        String routerName = StringUtils.capitalize(path);
-        // 闈炲閾惧苟涓旀槸涓�绾х洰褰曪紙绫诲瀷涓虹洰褰曪級
-        if (isMenuFrame()) {
-            routerName = StringUtils.EMPTY;
-        }
-        return routerName;
-    }
-
-    /**
-     * 鑾峰彇璺敱鍦板潃
-     */
-    public String getRouterPath() {
-        String routerPath = this.path;
-        // 鍐呴摼鎵撳紑澶栫綉鏂瑰紡
-        if (getParentId() != 0L && isInnerLink()) {
-            routerPath = innerLinkReplaceEach(routerPath);
-        }
-        // 闈炲閾惧苟涓旀槸涓�绾х洰褰曪紙绫诲瀷涓虹洰褰曪級
-        if (0L == getParentId() && UserConstants.TYPE_DIR.equals(getMenuType())
-            && UserConstants.NO_FRAME.equals(getIsFrame())) {
-            routerPath = "/" + this.path;
-        }
-        // 闈炲閾惧苟涓旀槸涓�绾х洰褰曪紙绫诲瀷涓鸿彍鍗曪級
-        else if (isMenuFrame()) {
-            routerPath = "/";
-        }
-        return routerPath;
-    }
-
-    /**
-     * 鑾峰彇缁勪欢淇℃伅
-     */
-    public String getComponentInfo() {
-        String component = UserConstants.LAYOUT;
-        if (StringUtils.isNotEmpty(this.component) && !isMenuFrame()) {
-            component = this.component;
-        } else if (StringUtils.isEmpty(this.component) && getParentId() != 0L && isInnerLink()) {
-            component = UserConstants.INNER_LINK;
-        } else if (StringUtils.isEmpty(this.component) && isParentView()) {
-            component = UserConstants.PARENT_VIEW;
-        }
-        return component;
-    }
-
-    /**
-     * 鏄惁涓鸿彍鍗曞唴閮ㄨ烦杞�
-     */
-    public boolean isMenuFrame() {
-        return getParentId() == 0L && UserConstants.TYPE_MENU.equals(menuType) && isFrame.equals(UserConstants.NO_FRAME);
-    }
-
-    /**
-     * 鏄惁涓哄唴閾剧粍浠�
-     */
-    public boolean isInnerLink() {
-        return isFrame.equals(UserConstants.NO_FRAME) && StringUtils.ishttp(path);
-    }
-
-    /**
-     * 鏄惁涓簆arent_view缁勪欢
-     */
-    public boolean isParentView() {
-        return getParentId() != 0L && UserConstants.TYPE_DIR.equals(menuType);
-    }
-
-    /**
-     * 鍐呴摼鍩熷悕鐗规畩瀛楃鏇挎崲
-     */
-    public static String innerLinkReplaceEach(String path) {
-        return StringUtils.replaceEach(path, new String[]{Constants.HTTP, Constants.HTTPS, Constants.WWW, "."},
-            new String[]{"", "", "", "/"});
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysNotice.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysNotice.java
deleted file mode 100644
index f61fd8c..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysNotice.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.ruoyi.system.domain;
-
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.ruoyi.common.tenant.core.TenantEntity;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-
-/**
- * 閫氱煡鍏憡琛� sys_notice
- *
- * @author Lion Li
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("sys_notice")
-public class SysNotice extends TenantEntity {
-
-    /**
-     * 鍏憡ID
-     */
-    @TableId(value = "notice_id")
-    private Long noticeId;
-
-    /**
-     * 鍏憡鏍囬
-     */
-    private String noticeTitle;
-
-    /**
-     * 鍏憡绫诲瀷锛�1閫氱煡 2鍏憡锛�
-     */
-    private String noticeType;
-
-    /**
-     * 鍏憡鍐呭
-     */
-    private String noticeContent;
-
-    /**
-     * 鍏憡鐘舵�侊紙0姝e父 1鍏抽棴锛�
-     */
-    private String status;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOperLog.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOperLog.java
deleted file mode 100644
index 4544a4d..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOperLog.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package com.ruoyi.system.domain;
-
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-
-/**
- * 鎿嶄綔鏃ュ織璁板綍琛� oper_log
- *
- * @author Lion Li
- */
-
-@Data
-@TableName("sys_oper_log")
-public class SysOperLog implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 鏃ュ織涓婚敭
-     */
-    @TableId(value = "oper_id")
-    private Long operId;
-
-    /**
-     * 绉熸埛缂栧彿
-     */
-    private String tenantId;
-
-    /**
-     * 鎿嶄綔妯″潡
-     */
-    private String title;
-
-    /**
-     * 涓氬姟绫诲瀷锛�0鍏跺畠 1鏂板 2淇敼 3鍒犻櫎锛�
-     */
-    private Integer businessType;
-
-    /**
-     * 璇锋眰鏂规硶
-     */
-    private String method;
-
-    /**
-     * 璇锋眰鏂瑰紡
-     */
-    private String requestMethod;
-
-    /**
-     * 鎿嶄綔绫诲埆锛�0鍏跺畠 1鍚庡彴鐢ㄦ埛 2鎵嬫満绔敤鎴凤級
-     */
-    private Integer operatorType;
-
-    /**
-     * 鎿嶄綔浜哄憳
-     */
-    private String operName;
-
-    /**
-     * 閮ㄩ棬鍚嶇О
-     */
-    private String deptName;
-
-    /**
-     * 璇锋眰url
-     */
-    private String operUrl;
-
-    /**
-     * 鎿嶄綔鍦板潃
-     */
-    private String operIp;
-
-    /**
-     * 鎿嶄綔鍦扮偣
-     */
-    private String operLocation;
-
-    /**
-     * 璇锋眰鍙傛暟
-     */
-    private String operParam;
-
-    /**
-     * 杩斿洖鍙傛暟
-     */
-    private String jsonResult;
-
-    /**
-     * 鎿嶄綔鐘舵�侊紙0姝e父 1寮傚父锛�
-     */
-    private Integer status;
-
-    /**
-     * 閿欒娑堟伅
-     */
-    private String errorMsg;
-
-    /**
-     * 鎿嶄綔鏃堕棿
-     */
-    private Date operTime;
-
-    /**
-     * 娑堣�楁椂闂�
-     */
-    private Long costTime;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOss.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOss.java
deleted file mode 100644
index 1f74be0..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOss.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.ruoyi.system.domain;
-
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.ruoyi.common.tenant.core.TenantEntity;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * OSS瀵硅薄瀛樺偍瀵硅薄
- *
- * @author Lion Li
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("sys_oss")
-public class SysOss extends TenantEntity {
-
-    /**
-     * 瀵硅薄瀛樺偍涓婚敭
-     */
-    @TableId(value = "oss_id")
-    private Long ossId;
-
-    /**
-     * 鏂囦欢鍚�
-     */
-    private String fileName;
-
-    /**
-     * 鍘熷悕
-     */
-    private String originalName;
-
-    /**
-     * 鏂囦欢鍚庣紑鍚�
-     */
-    private String fileSuffix;
-
-    /**
-     * URL鍦板潃
-     */
-    private String url;
-
-    /**
-     * 鏈嶅姟鍟�
-     */
-    private String service;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOssConfig.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOssConfig.java
deleted file mode 100644
index 8623f1a..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysOssConfig.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package com.ruoyi.system.domain;
-
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.ruoyi.common.tenant.core.TenantEntity;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * 瀵硅薄瀛樺偍閰嶇疆瀵硅薄 sys_oss_config
- *
- * @author Lion Li
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("sys_oss_config")
-public class SysOssConfig extends TenantEntity {
-
-    /**
-     * 涓诲缓
-     */
-    @TableId(value = "oss_config_id")
-    private Long ossConfigId;
-
-    /**
-     * 閰嶇疆key
-     */
-    private String configKey;
-
-    /**
-     * accessKey
-     */
-    private String accessKey;
-
-    /**
-     * 绉橀挜
-     */
-    private String secretKey;
-
-    /**
-     * 妗跺悕绉�
-     */
-    private String bucketName;
-
-    /**
-     * 鍓嶇紑
-     */
-    private String prefix;
-
-    /**
-     * 璁块棶绔欑偣
-     */
-    private String endpoint;
-
-    /**
-     * 鑷畾涔夊煙鍚�
-     */
-    private String domain;
-
-    /**
-     * 鏄惁https锛�0鍚� 1鏄級
-     */
-    private String isHttps;
-
-    /**
-     * 鍩�
-     */
-    private String region;
-
-    /**
-     * 鏄惁榛樿锛�0=鏄�,1=鍚︼級
-     */
-    private String status;
-
-    /**
-     * 鎵╁睍瀛楁
-     */
-    private String ext1;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-    /**
-     * 妗舵潈闄愮被鍨�(0private 1public 2custom)
-     */
-    private String accessPolicy;
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysPost.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysPost.java
deleted file mode 100644
index 970dd4d..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysPost.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.ruoyi.system.domain;
-
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.ruoyi.common.tenant.core.TenantEntity;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * 宀椾綅琛� sys_post
- *
- * @author Lion Li
- */
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("sys_post")
-public class SysPost extends TenantEntity {
-
-    /**
-     * 宀椾綅搴忓彿
-     */
-    @TableId(value = "post_id")
-    private Long postId;
-
-    /**
-     * 宀椾綅缂栫爜
-     */
-    private String postCode;
-
-    /**
-     * 宀椾綅鍚嶇О
-     */
-    private String postName;
-
-    /**
-     * 宀椾綅鎺掑簭
-     */
-    private Integer postSort;
-
-    /**
-     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    private String status;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRole.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRole.java
deleted file mode 100644
index f4d3f30..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRole.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package com.ruoyi.system.domain;
-
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableLogic;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.ruoyi.common.tenant.core.TenantEntity;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
-
-/**
- * 瑙掕壊琛� sys_role
- *
- * @author Lion Li
- */
-
-@Data
-@NoArgsConstructor
-@EqualsAndHashCode(callSuper = true)
-@TableName("sys_role")
-public class SysRole extends TenantEntity {
-
-    /**
-     * 瑙掕壊ID
-     */
-    @TableId(value = "role_id")
-    private Long roleId;
-
-    /**
-     * 瑙掕壊鍚嶇О
-     */
-    private String roleName;
-
-    /**
-     * 瑙掕壊鏉冮檺
-     */
-    private String roleKey;
-
-    /**
-     * 瑙掕壊鎺掑簭
-     */
-    private Integer roleSort;
-
-    /**
-     * 鏁版嵁鑼冨洿锛�1锛氭墍鏈夋暟鎹潈闄愶紱2锛氳嚜瀹氫箟鏁版嵁鏉冮檺锛�3锛氭湰閮ㄩ棬鏁版嵁鏉冮檺锛�4锛氭湰閮ㄩ棬鍙婁互涓嬫暟鎹潈闄愶紱5锛氫粎鏈汉鏁版嵁鏉冮檺锛�
-     */
-    private String dataScope;
-
-    /**
-     * 鑿滃崟鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀猴紙 0锛氱埗瀛愪笉浜掔浉鍏宠仈鏄剧ず 1锛氱埗瀛愪簰鐩稿叧鑱旀樉绀猴級
-     */
-    private Boolean menuCheckStrictly;
-
-    /**
-     * 閮ㄩ棬鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀猴紙0锛氱埗瀛愪笉浜掔浉鍏宠仈鏄剧ず 1锛氱埗瀛愪簰鐩稿叧鑱旀樉绀� 锛�
-     */
-    private Boolean deptCheckStrictly;
-
-    /**
-     * 瑙掕壊鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    private String status;
-
-    /**
-     * 鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛�
-     */
-    @TableLogic
-    private String delFlag;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-    public SysRole(Long roleId) {
-        this.roleId = roleId;
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleDept.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleDept.java
deleted file mode 100644
index 38e7048..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleDept.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.ruoyi.system.domain;
-
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-
-/**
- * 瑙掕壊鍜岄儴闂ㄥ叧鑱� sys_role_dept
- *
- * @author Lion Li
- */
-
-@Data
-@TableName("sys_role_dept")
-public class SysRoleDept {
-
-    /**
-     * 瑙掕壊ID
-     */
-    @TableId(type = IdType.INPUT)
-    private Long roleId;
-
-    /**
-     * 閮ㄩ棬ID
-     */
-    private Long deptId;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleMenu.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleMenu.java
deleted file mode 100644
index dd359c4..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleMenu.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.ruoyi.system.domain;
-
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-
-/**
- * 瑙掕壊鍜岃彍鍗曞叧鑱� sys_role_menu
- *
- * @author Lion Li
- */
-
-@Data
-@TableName("sys_role_menu")
-public class SysRoleMenu {
-
-    /**
-     * 瑙掕壊ID
-     */
-    @TableId(type = IdType.INPUT)
-    private Long roleId;
-
-    /**
-     * 鑿滃崟ID
-     */
-    private Long menuId;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTenant.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTenant.java
deleted file mode 100644
index e65fdf5..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTenant.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package com.ruoyi.system.domain;
-
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableLogic;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import java.io.Serial;
-import java.util.Date;
-
-/**
- * 绉熸埛瀵硅薄 sys_tenant
- *
- * @author Michelle.Chung
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("sys_tenant")
-public class SysTenant extends BaseEntity {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * id
-     */
-    @TableId(value = "id")
-    private Long id;
-
-    /**
-     * 绉熸埛缂栧彿
-     */
-    private String tenantId;
-
-    /**
-     * 鑱旂郴浜�
-     */
-    private String contactUserName;
-
-    /**
-     * 鑱旂郴鐢佃瘽
-     */
-    private String contactPhone;
-
-    /**
-     * 浼佷笟鍚嶇О
-     */
-    private String companyName;
-
-    /**
-     * 缁熶竴绀句細淇$敤浠g爜
-     */
-    private String licenseNumber;
-
-    /**
-     * 鍦板潃
-     */
-    private String address;
-
-    /**
-     * 鍩熷悕
-     */
-    private String domain;
-
-    /**
-     * 浼佷笟绠�浠�
-     */
-    private String intro;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-    /**
-     * 绉熸埛濂楅缂栧彿
-     */
-    private Long packageId;
-
-    /**
-     * 杩囨湡鏃堕棿
-     */
-    private Date expireTime;
-
-    /**
-     * 鐢ㄦ埛鏁伴噺锛�-1涓嶉檺鍒讹級
-     */
-    private Long accountCount;
-
-    /**
-     * 绉熸埛鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    private String status;
-
-    /**
-     * 鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛�
-     */
-    @TableLogic
-    private String delFlag;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTenantPackage.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTenantPackage.java
deleted file mode 100644
index c8ceef6..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTenantPackage.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.ruoyi.system.domain;
-
-import com.baomidou.mybatisplus.annotation.*;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import java.io.Serial;
-
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-
-/**
- * 绉熸埛濂楅瀵硅薄 sys_tenant_package
- *
- * @author Michelle.Chung
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("sys_tenant_package")
-public class SysTenantPackage extends BaseEntity {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 绉熸埛濂楅id
-     */
-    @TableId(value = "package_id")
-    private Long packageId;
-    /**
-     * 濂楅鍚嶇О
-     */
-    private String packageName;
-    /**
-     * 鍏宠仈鑿滃崟id
-     */
-    private String menuIds;
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-    /**
-     * 鑿滃崟鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀猴紙 0锛氱埗瀛愪笉浜掔浉鍏宠仈鏄剧ず 1锛氱埗瀛愪簰鐩稿叧鑱旀樉绀猴級
-     */
-    private Boolean menuCheckStrictly;
-    /**
-     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    private String status;
-    /**
-     * 鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛�
-     */
-    @TableLogic
-    private String delFlag;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUser.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUser.java
deleted file mode 100644
index 18e11c5..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUser.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package com.ruoyi.system.domain;
-
-import com.baomidou.mybatisplus.annotation.*;
-import com.ruoyi.common.core.constant.UserConstants;
-import com.ruoyi.common.tenant.core.TenantEntity;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
-
-import java.util.Date;
-
-/**
- * 鐢ㄦ埛瀵硅薄 sys_user
- *
- * @author Lion Li
- */
-
-@Data
-@NoArgsConstructor
-@EqualsAndHashCode(callSuper = true)
-@TableName("sys_user")
-public class SysUser extends TenantEntity {
-
-    /**
-     * 鐢ㄦ埛ID
-     */
-    @TableId(value = "user_id")
-    private Long userId;
-
-    /**
-     * 閮ㄩ棬ID
-     */
-    private Long deptId;
-
-    /**
-     * 鐢ㄦ埛璐﹀彿
-     */
-    private String userName;
-
-    /**
-     * 鐢ㄦ埛鏄电О
-     */
-    private String nickName;
-
-    /**
-     * 鐢ㄦ埛绫诲瀷锛坰ys_user绯荤粺鐢ㄦ埛锛�
-     */
-    private String userType;
-
-    /**
-     * 鐢ㄦ埛閭
-     */
-    private String email;
-
-    /**
-     * 鎵嬫満鍙风爜
-     */
-    private String phonenumber;
-
-    /**
-     * 鐢ㄦ埛鎬у埆
-     */
-    private String sex;
-
-    /**
-     * 鐢ㄦ埛澶村儚
-     */
-    private Long avatar;
-
-    /**
-     * 瀵嗙爜
-     */
-    @TableField(
-        insertStrategy = FieldStrategy.NOT_EMPTY,
-        updateStrategy = FieldStrategy.NOT_EMPTY,
-        whereStrategy = FieldStrategy.NOT_EMPTY
-    )
-    private String password;
-
-    /**
-     * 甯愬彿鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    private String status;
-
-    /**
-     * 鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛�
-     */
-    @TableLogic
-    private String delFlag;
-
-    /**
-     * 鏈�鍚庣櫥褰旾P
-     */
-    private String loginIp;
-
-    /**
-     * 鏈�鍚庣櫥褰曟椂闂�
-     */
-    private Date loginDate;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-
-    public SysUser(Long userId) {
-        this.userId = userId;
-    }
-
-    public boolean isSuperAdmin() {
-        return UserConstants.SUPER_ADMIN_ID.equals(this.userId);
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserOnline.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserOnline.java
deleted file mode 100644
index e8fa5bf..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserOnline.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.ruoyi.system.domain;
-
-import lombok.Data;
-
-/**
- * 褰撳墠鍦ㄧ嚎浼氳瘽
- *
- * @author Lion Li
- */
-
-@Data
-public class SysUserOnline {
-
-    /**
-     * 浼氳瘽缂栧彿
-     */
-    private String tokenId;
-
-    /**
-     * 閮ㄩ棬鍚嶇О
-     */
-    private String deptName;
-
-    /**
-     * 鐢ㄦ埛鍚嶇О
-     */
-    private String userName;
-
-    /**
-     * 鐧诲綍IP鍦板潃
-     */
-    private String ipaddr;
-
-    /**
-     * 鐧诲綍鍦板潃
-     */
-    private String loginLocation;
-
-    /**
-     * 娴忚鍣ㄧ被鍨�
-     */
-    private String browser;
-
-    /**
-     * 鎿嶄綔绯荤粺
-     */
-    private String os;
-
-    /**
-     * 鐧诲綍鏃堕棿
-     */
-    private Long loginTime;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserPost.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserPost.java
deleted file mode 100644
index a698055..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserPost.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.ruoyi.system.domain;
-
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-
-/**
- * 鐢ㄦ埛鍜屽矖浣嶅叧鑱� sys_user_post
- *
- * @author Lion Li
- */
-
-@Data
-@TableName("sys_user_post")
-public class SysUserPost {
-
-    /**
-     * 鐢ㄦ埛ID
-     */
-    @TableId(type = IdType.INPUT)
-    private Long userId;
-
-    /**
-     * 宀椾綅ID
-     */
-    private Long postId;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserRole.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserRole.java
deleted file mode 100644
index 8d35437..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserRole.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.ruoyi.system.domain;
-
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-
-/**
- * 鐢ㄦ埛鍜岃鑹插叧鑱� sys_user_role
- *
- * @author Lion Li
- */
-
-@Data
-@TableName("sys_user_role")
-public class SysUserRole {
-
-    /**
-     * 鐢ㄦ埛ID
-     */
-    @TableId(type = IdType.INPUT)
-    private Long userId;
-
-    /**
-     * 瑙掕壊ID
-     */
-    private Long roleId;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysConfigBo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysConfigBo.java
deleted file mode 100644
index 68f3b9b..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysConfigBo.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.ruoyi.system.domain.bo;
-
-import com.ruoyi.common.core.validate.AddGroup;
-import com.ruoyi.common.core.validate.EditGroup;
-import com.ruoyi.system.domain.SysConfig;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import jakarta.validation.constraints.*;
-
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-
-/**
- * 鍙傛暟閰嶇疆涓氬姟瀵硅薄 sys_config
- *
- * @author Michelle.Chung
- */
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@AutoMapper(target = SysConfig.class, reverseConvertGenerate = false)
-public class SysConfigBo extends BaseEntity {
-
-    /**
-     * 鍙傛暟涓婚敭
-     */
-    @NotNull(message = "鍙傛暟涓婚敭涓嶈兘涓虹┖", groups = { EditGroup.class })
-    private Long configId;
-
-    /**
-     * 鍙傛暟鍚嶇О
-     */
-    @NotBlank(message = "鍙傛暟鍚嶇О涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
-    @Size(min = 0, max = 100, message = "鍙傛暟鍚嶇О涓嶈兘瓒呰繃{max}涓瓧绗�")
-    private String configName;
-
-    /**
-     * 鍙傛暟閿悕
-     */
-    @NotBlank(message = "鍙傛暟閿悕涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
-    @Size(min = 0, max = 100, message = "鍙傛暟閿悕闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
-    private String configKey;
-
-    /**
-     * 鍙傛暟閿��
-     */
-    @NotBlank(message = "鍙傛暟閿�间笉鑳戒负绌�", groups = { AddGroup.class, EditGroup.class })
-    @Size(min = 0, max = 500, message = "鍙傛暟閿�奸暱搴︿笉鑳借秴杩噞max}涓瓧绗�")
-    private String configValue;
-
-    /**
-     * 绯荤粺鍐呯疆锛圷鏄� N鍚︼級
-     */
-    private String configType;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysDeptBo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysDeptBo.java
deleted file mode 100644
index 3efdefd..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysDeptBo.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.ruoyi.system.domain.bo;
-
-import com.ruoyi.common.core.validate.AddGroup;
-import com.ruoyi.common.core.validate.EditGroup;
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-import com.ruoyi.system.domain.SysDept;
-import io.github.linpeilie.annotations.AutoMapper;
-import jakarta.validation.constraints.Email;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import jakarta.validation.constraints.Size;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * 閮ㄩ棬涓氬姟瀵硅薄 sys_dept
- *
- * @author Michelle.Chung
- */
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@AutoMapper(target = SysDept.class, reverseConvertGenerate = false)
-public class SysDeptBo extends BaseEntity {
-
-    /**
-     * 閮ㄩ棬id
-     */
-    @NotNull(message = "閮ㄩ棬id涓嶈兘涓虹┖", groups = { EditGroup.class })
-    private Long deptId;
-
-    /**
-     * 鐖堕儴闂↖D
-     */
-    private Long parentId;
-
-    /**
-     * 閮ㄩ棬鍚嶇О
-     */
-    @NotBlank(message = "閮ㄩ棬鍚嶇О涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
-    @Size(min = 0, max = 30, message = "閮ㄩ棬鍚嶇О闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
-    private String deptName;
-
-    /**
-     * 鏄剧ず椤哄簭
-     */
-    @NotNull(message = "鏄剧ず椤哄簭涓嶈兘涓虹┖")
-    private Integer orderNum;
-
-    /**
-     * 璐熻矗浜�
-     */
-    private String leader;
-
-    /**
-     * 鑱旂郴鐢佃瘽
-     */
-    @Size(min = 0, max = 11, message = "鑱旂郴鐢佃瘽闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
-    private String phone;
-
-    /**
-     * 閭
-     */
-    @Email(message = "閭鏍煎紡涓嶆纭�")
-    @Size(min = 0, max = 50, message = "閭闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
-    private String email;
-
-    /**
-     * 閮ㄩ棬鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    private String status;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysDictDataBo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysDictDataBo.java
deleted file mode 100644
index 5af3c51..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysDictDataBo.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package com.ruoyi.system.domain.bo;
-
-import com.ruoyi.common.core.validate.AddGroup;
-import com.ruoyi.common.core.validate.EditGroup;
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-import com.ruoyi.system.domain.SysDictData;
-import io.github.linpeilie.annotations.AutoMapper;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import jakarta.validation.constraints.Size;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * 瀛楀吀鏁版嵁涓氬姟瀵硅薄 sys_dict_data
- *
- * @author Michelle.Chung
- */
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@AutoMapper(target = SysDictData.class, reverseConvertGenerate = false)
-public class SysDictDataBo extends BaseEntity {
-
-    /**
-     * 瀛楀吀缂栫爜
-     */
-    @NotNull(message = "瀛楀吀缂栫爜涓嶈兘涓虹┖", groups = { EditGroup.class })
-    private Long dictCode;
-
-    /**
-     * 瀛楀吀鎺掑簭
-     */
-    private Integer dictSort;
-
-    /**
-     * 瀛楀吀鏍囩
-     */
-    @NotBlank(message = "瀛楀吀鏍囩涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
-    @Size(min = 0, max = 100, message = "瀛楀吀鏍囩闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
-    private String dictLabel;
-
-    /**
-     * 瀛楀吀閿��
-     */
-    @NotBlank(message = "瀛楀吀閿�间笉鑳戒负绌�", groups = { AddGroup.class, EditGroup.class })
-    @Size(min = 0, max = 100, message = "瀛楀吀閿�奸暱搴︿笉鑳借秴杩噞max}涓瓧绗�")
-    private String dictValue;
-
-    /**
-     * 瀛楀吀绫诲瀷
-     */
-    @NotBlank(message = "瀛楀吀绫诲瀷涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
-    @Size(min = 0, max = 100, message = "瀛楀吀绫诲瀷闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
-    private String dictType;
-
-    /**
-     * 鏍峰紡灞炴�э紙鍏朵粬鏍峰紡鎵╁睍锛�
-     */
-    @Size(min = 0, max = 100, message = "鏍峰紡灞炴�ч暱搴︿笉鑳借秴杩噞max}涓瓧绗�")
-    private String cssClass;
-
-    /**
-     * 琛ㄦ牸鍥炴樉鏍峰紡
-     */
-    private String listClass;
-
-    /**
-     * 鏄惁榛樿锛圷鏄� N鍚︼級
-     */
-    private String isDefault;
-
-    /**
-     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    private String status;
-
-    /**
-     * 鍒涘缓閮ㄩ棬
-     */
-    private Long createDept;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysDictTypeBo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysDictTypeBo.java
deleted file mode 100644
index 2f87234..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysDictTypeBo.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package com.ruoyi.system.domain.bo;
-
-import com.ruoyi.common.core.validate.AddGroup;
-import com.ruoyi.common.core.validate.EditGroup;
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-import com.ruoyi.system.domain.SysDictType;
-import io.github.linpeilie.annotations.AutoMapper;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import jakarta.validation.constraints.Pattern;
-import jakarta.validation.constraints.Size;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * 瀛楀吀绫诲瀷涓氬姟瀵硅薄 sys_dict_type
- *
- * @author Michelle.Chung
- */
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@AutoMapper(target = SysDictType.class, reverseConvertGenerate = false)
-public class SysDictTypeBo extends BaseEntity {
-
-    /**
-     * 瀛楀吀涓婚敭
-     */
-    @NotNull(message = "瀛楀吀涓婚敭涓嶈兘涓虹┖", groups = { EditGroup.class })
-    private Long dictId;
-
-    /**
-     * 瀛楀吀鍚嶇О
-     */
-    @NotBlank(message = "瀛楀吀鍚嶇О涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
-    @Size(min = 0, max = 100, message = "瀛楀吀绫诲瀷鍚嶇О闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
-    private String dictName;
-
-    /**
-     * 瀛楀吀绫诲瀷
-     */
-    @NotBlank(message = "瀛楀吀绫诲瀷涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
-    @Size(min = 0, max = 100, message = "瀛楀吀绫诲瀷绫诲瀷闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
-    @Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "瀛楀吀绫诲瀷蹇呴』浠ュ瓧姣嶅紑澶达紝涓斿彧鑳戒负锛堝皬鍐欏瓧姣嶏紝鏁板瓧锛屼笅婊戠嚎锛�")
-    private String dictType;
-
-    /**
-     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    private String status;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysLogininforBo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysLogininforBo.java
deleted file mode 100644
index 7209b17..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysLogininforBo.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package com.ruoyi.system.domain.bo;
-
-import com.ruoyi.system.domain.SysLogininfor;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * 绯荤粺璁块棶璁板綍涓氬姟瀵硅薄 sys_logininfor
- *
- * @author Michelle.Chung
- */
-
-@Data
-@AutoMapper(target = SysLogininfor.class, reverseConvertGenerate = false)
-public class SysLogininforBo {
-
-    /**
-     * 璁块棶ID
-     */
-    private Long infoId;
-
-    /**
-     * 绉熸埛缂栧彿
-     */
-    private String tenantId;
-
-    /**
-     * 鐢ㄦ埛璐﹀彿
-     */
-    private String userName;
-
-    /**
-     * 鐧诲綍IP鍦板潃
-     */
-    private String ipaddr;
-
-    /**
-     * 鐧诲綍鍦扮偣
-     */
-    private String loginLocation;
-
-    /**
-     * 娴忚鍣ㄧ被鍨�
-     */
-    private String browser;
-
-    /**
-     * 鎿嶄綔绯荤粺
-     */
-    private String os;
-
-    /**
-     * 鐧诲綍鐘舵�侊紙0鎴愬姛 1澶辫触锛�
-     */
-    private String status;
-
-    /**
-     * 鎻愮ず娑堟伅
-     */
-    private String msg;
-
-    /**
-     * 璁块棶鏃堕棿
-     */
-    private Date loginTime;
-
-    /**
-     * 璇锋眰鍙傛暟
-     */
-    private Map<String, Object> params = new HashMap<>();
-
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysMenuBo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysMenuBo.java
deleted file mode 100644
index 5cb977d..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysMenuBo.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package com.ruoyi.system.domain.bo;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.ruoyi.common.core.validate.AddGroup;
-import com.ruoyi.common.core.validate.EditGroup;
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-import com.ruoyi.system.domain.SysMenu;
-import io.github.linpeilie.annotations.AutoMapper;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import jakarta.validation.constraints.Size;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * 鑿滃崟鏉冮檺涓氬姟瀵硅薄 sys_menu
- *
- * @author Michelle.Chung
- */
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@AutoMapper(target = SysMenu.class, reverseConvertGenerate = false)
-public class SysMenuBo extends BaseEntity {
-
-    /**
-     * 鑿滃崟ID
-     */
-    @NotNull(message = "鑿滃崟ID涓嶈兘涓虹┖", groups = { EditGroup.class })
-    private Long menuId;
-
-    /**
-     * 鐖惰彍鍗旾D
-     */
-    private Long parentId;
-
-    /**
-     * 鑿滃崟鍚嶇О
-     */
-    @NotBlank(message = "鑿滃崟鍚嶇О涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
-    @Size(min = 0, max = 50, message = "鑿滃崟鍚嶇О闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
-    private String menuName;
-
-    /**
-     * 鏄剧ず椤哄簭
-     */
-    @NotNull(message = "鏄剧ず椤哄簭涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
-    private Integer orderNum;
-
-    /**
-     * 璺敱鍦板潃
-     */
-    @Size(min = 0, max = 200, message = "璺敱鍦板潃涓嶈兘瓒呰繃{max}涓瓧绗�")
-    private String path;
-
-    /**
-     * 缁勪欢璺緞
-     */
-    @Size(min = 0, max = 200, message = "缁勪欢璺緞涓嶈兘瓒呰繃{max}涓瓧绗�")
-    private String component;
-
-    /**
-     * 璺敱鍙傛暟
-     */
-    private String queryParam;
-
-    /**
-     * 鏄惁涓哄閾撅紙0鏄� 1鍚︼級
-     */
-    private String isFrame;
-
-    /**
-     * 鏄惁缂撳瓨锛�0缂撳瓨 1涓嶇紦瀛橈級
-     */
-    private String isCache;
-
-    /**
-     * 鑿滃崟绫诲瀷锛圡鐩綍 C鑿滃崟 F鎸夐挳锛�
-     */
-    @NotBlank(message = "鑿滃崟绫诲瀷涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
-    private String menuType;
-
-    /**
-     * 鏄剧ず鐘舵�侊紙0鏄剧ず 1闅愯棌锛�
-     */
-    private String visible;
-
-    /**
-     * 鑿滃崟鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    private String status;
-
-    /**
-     * 鏉冮檺鏍囪瘑
-     */
-    @JsonInclude(JsonInclude.Include.NON_NULL)
-    @Size(min = 0, max = 100, message = "鏉冮檺鏍囪瘑闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
-    private String perms;
-
-    /**
-     * 鑿滃崟鍥炬爣
-     */
-    private String icon;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysNoticeBo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysNoticeBo.java
deleted file mode 100644
index f79e58e..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysNoticeBo.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.ruoyi.system.domain.bo;
-
-import com.ruoyi.common.core.validate.AddGroup;
-import com.ruoyi.common.core.validate.EditGroup;
-import com.ruoyi.common.core.xss.Xss;
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-import com.ruoyi.system.domain.SysNotice;
-import io.github.linpeilie.annotations.AutoMapper;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import jakarta.validation.constraints.Size;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * 閫氱煡鍏憡涓氬姟瀵硅薄 sys_notice
- *
- * @author Michelle.Chung
- */
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@AutoMapper(target = SysNotice.class, reverseConvertGenerate = false)
-public class SysNoticeBo extends BaseEntity {
-
-    /**
-     * 鍏憡ID
-     */
-    @NotNull(message = "鍏憡ID涓嶈兘涓虹┖", groups = { EditGroup.class })
-    private Long noticeId;
-
-    /**
-     * 鍏憡鏍囬
-     */
-    @Xss(message = "鍏憡鏍囬涓嶈兘鍖呭惈鑴氭湰瀛楃")
-    @NotBlank(message = "鍏憡鏍囬涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
-    @Size(min = 0, max = 50, message = "鍏憡鏍囬涓嶈兘瓒呰繃{max}涓瓧绗�")
-    private String noticeTitle;
-
-    /**
-     * 鍏憡绫诲瀷锛�1閫氱煡 2鍏憡锛�
-     */
-    private String noticeType;
-
-    /**
-     * 鍏憡鍐呭
-     */
-    private String noticeContent;
-
-    /**
-     * 鍏憡鐘舵�侊紙0姝e父 1鍏抽棴锛�
-     */
-    private String status;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-    /**
-     * 鍒涘缓浜哄悕绉�
-     */
-    private String createByName;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysOperLogBo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysOperLogBo.java
deleted file mode 100644
index 4ebdb86..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysOperLogBo.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package com.ruoyi.system.domain.bo;
-
-import com.ruoyi.common.log.event.OperLogEvent;
-import com.ruoyi.system.domain.SysOperLog;
-import io.github.linpeilie.annotations.AutoMapper;
-import io.github.linpeilie.annotations.AutoMappers;
-import lombok.Data;
-
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * 鎿嶄綔鏃ュ織璁板綍涓氬姟瀵硅薄 sys_oper_log
- *
- * @author Michelle.Chung
- * @date 2023-02-07
- */
-
-@Data
-@AutoMappers({
-    @AutoMapper(target = SysOperLog.class, reverseConvertGenerate = false),
-    @AutoMapper(target = OperLogEvent.class)
-})
-public class SysOperLogBo {
-
-    /**
-     * 鏃ュ織涓婚敭
-     */
-    private Long operId;
-
-    /**
-     * 绉熸埛缂栧彿
-     */
-    private String tenantId;
-
-    /**
-     * 妯″潡鏍囬
-     */
-    private String title;
-
-    /**
-     * 涓氬姟绫诲瀷锛�0鍏跺畠 1鏂板 2淇敼 3鍒犻櫎锛�
-     */
-    private Integer businessType;
-
-    /**
-     * 涓氬姟绫诲瀷鏁扮粍
-     */
-    private Integer[] businessTypes;
-
-    /**
-     * 鏂规硶鍚嶇О
-     */
-    private String method;
-
-    /**
-     * 璇锋眰鏂瑰紡
-     */
-    private String requestMethod;
-
-    /**
-     * 鎿嶄綔绫诲埆锛�0鍏跺畠 1鍚庡彴鐢ㄦ埛 2鎵嬫満绔敤鎴凤級
-     */
-    private Integer operatorType;
-
-    /**
-     * 鎿嶄綔浜哄憳
-     */
-    private String operName;
-
-    /**
-     * 閮ㄩ棬鍚嶇О
-     */
-    private String deptName;
-
-    /**
-     * 璇锋眰URL
-     */
-    private String operUrl;
-
-    /**
-     * 涓绘満鍦板潃
-     */
-    private String operIp;
-
-    /**
-     * 鎿嶄綔鍦扮偣
-     */
-    private String operLocation;
-
-    /**
-     * 璇锋眰鍙傛暟
-     */
-    private String operParam;
-
-    /**
-     * 杩斿洖鍙傛暟
-     */
-    private String jsonResult;
-
-    /**
-     * 鎿嶄綔鐘舵�侊紙0姝e父 1寮傚父锛�
-     */
-    private Integer status;
-
-    /**
-     * 閿欒娑堟伅
-     */
-    private String errorMsg;
-
-    /**
-     * 鎿嶄綔鏃堕棿
-     */
-    private Date operTime;
-
-    /**
-     * 娑堣�楁椂闂�
-     */
-    private Long costTime;
-
-    /**
-     * 璇锋眰鍙傛暟
-     */
-    private Map<String, Object> params = new HashMap<>();
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysOssBo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysOssBo.java
deleted file mode 100644
index 85e7c62..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysOssBo.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.ruoyi.system.domain.bo;
-
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-import com.ruoyi.system.domain.SysOss;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * OSS瀵硅薄瀛樺偍鍒嗛〉鏌ヨ瀵硅薄 sys_oss
- *
- * @author Lion Li
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@AutoMapper(target = SysOss.class, reverseConvertGenerate = false)
-public class SysOssBo extends BaseEntity {
-
-    /**
-     * ossId
-     */
-    private Long ossId;
-
-    /**
-     * 鏂囦欢鍚�
-     */
-    private String fileName;
-
-    /**
-     * 鍘熷悕
-     */
-    private String originalName;
-
-    /**
-     * 鏂囦欢鍚庣紑鍚�
-     */
-    private String fileSuffix;
-
-    /**
-     * URL鍦板潃
-     */
-    private String url;
-
-    /**
-     * 鏈嶅姟鍟�
-     */
-    private String service;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysOssConfigBo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysOssConfigBo.java
deleted file mode 100644
index 6174b5f..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysOssConfigBo.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package com.ruoyi.system.domain.bo;
-
-import com.ruoyi.common.core.validate.AddGroup;
-import com.ruoyi.common.core.validate.EditGroup;
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-import com.ruoyi.system.domain.SysOssConfig;
-import io.github.linpeilie.annotations.AutoMapper;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import jakarta.validation.constraints.Size;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * 瀵硅薄瀛樺偍閰嶇疆涓氬姟瀵硅薄 sys_oss_config
- *
- * @author Lion Li
- * @author 瀛よ垷鐑熼洦
- * @date 2021-08-13
- */
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@AutoMapper(target = SysOssConfig.class, reverseConvertGenerate = false)
-public class SysOssConfigBo extends BaseEntity {
-
-    /**
-     * 涓诲缓
-     */
-    @NotNull(message = "涓诲缓涓嶈兘涓虹┖", groups = {EditGroup.class})
-    private Long ossConfigId;
-
-    /**
-     * 閰嶇疆key
-     */
-    @NotBlank(message = "閰嶇疆key涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
-    @Size(min = 2, max = 100, message = "configKey闀垮害蹇呴』浠嬩簬{min}鍜寋max} 涔嬮棿")
-    private String configKey;
-
-    /**
-     * accessKey
-     */
-    @NotBlank(message = "accessKey涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
-    @Size(min = 2, max = 100, message = "accessKey闀垮害蹇呴』浠嬩簬{min}鍜寋max} 涔嬮棿")
-    private String accessKey;
-
-    /**
-     * 绉橀挜
-     */
-    @NotBlank(message = "secretKey涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
-    @Size(min = 2, max = 100, message = "secretKey闀垮害蹇呴』浠嬩簬{min}鍜寋max} 涔嬮棿")
-    private String secretKey;
-
-    /**
-     * 妗跺悕绉�
-     */
-    @NotBlank(message = "妗跺悕绉颁笉鑳戒负绌�", groups = {AddGroup.class, EditGroup.class})
-    @Size(min = 2, max = 100, message = "bucketName闀垮害蹇呴』浠嬩簬{min}鍜寋max}涔嬮棿")
-    private String bucketName;
-
-    /**
-     * 鍓嶇紑
-     */
-    private String prefix;
-
-    /**
-     * 璁块棶绔欑偣
-     */
-    @NotBlank(message = "璁块棶绔欑偣涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
-    @Size(min = 2, max = 100, message = "endpoint闀垮害蹇呴』浠嬩簬{min}鍜寋max}涔嬮棿")
-    private String endpoint;
-
-    /**
-     * 鑷畾涔夊煙鍚�
-     */
-    private String domain;
-
-    /**
-     * 鏄惁https锛圷=鏄�,N=鍚︼級
-     */
-    private String isHttps;
-
-    /**
-     * 鏄惁榛樿锛�0=鏄�,1=鍚︼級
-     */
-    private String status;
-
-    /**
-     * 鍩�
-     */
-    private String region;
-
-    /**
-     * 鎵╁睍瀛楁
-     */
-    private String ext1;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-    /**
-     * 妗舵潈闄愮被鍨�(0private 1public 2custom)
-     */
-    @NotBlank(message = "妗舵潈闄愮被鍨嬩笉鑳戒负绌�", groups = {AddGroup.class, EditGroup.class})
-    private String accessPolicy;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysPostBo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysPostBo.java
deleted file mode 100644
index c1fb2eb..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysPostBo.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.ruoyi.system.domain.bo;
-
-import com.ruoyi.common.core.validate.AddGroup;
-import com.ruoyi.common.core.validate.EditGroup;
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-import com.ruoyi.system.domain.SysPost;
-import io.github.linpeilie.annotations.AutoMapper;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import jakarta.validation.constraints.Size;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * 宀椾綅淇℃伅涓氬姟瀵硅薄 sys_post
- *
- * @author Michelle.Chung
- */
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@AutoMapper(target = SysPost.class, reverseConvertGenerate = false)
-public class SysPostBo extends BaseEntity {
-
-    /**
-     * 宀椾綅ID
-     */
-    @NotNull(message = "宀椾綅ID涓嶈兘涓虹┖", groups = { EditGroup.class })
-    private Long postId;
-
-    /**
-     * 宀椾綅缂栫爜
-     */
-    @NotBlank(message = "宀椾綅缂栫爜涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
-    @Size(min = 0, max = 64, message = "宀椾綅缂栫爜闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
-    private String postCode;
-
-    /**
-     * 宀椾綅鍚嶇О
-     */
-    @NotBlank(message = "宀椾綅鍚嶇О涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
-    @Size(min = 0, max = 50, message = "宀椾綅鍚嶇О闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
-    private String postName;
-
-    /**
-     * 鏄剧ず椤哄簭
-     */
-    @NotNull(message = "鏄剧ず椤哄簭涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
-    private Integer postSort;
-
-    /**
-     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    private String status;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysRoleBo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysRoleBo.java
deleted file mode 100644
index 713941e..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysRoleBo.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package com.ruoyi.system.domain.bo;
-
-import com.ruoyi.common.core.constant.UserConstants;
-import com.ruoyi.common.core.validate.AddGroup;
-import com.ruoyi.common.core.validate.EditGroup;
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-import com.ruoyi.system.domain.SysRole;
-import io.github.linpeilie.annotations.AutoMapper;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import jakarta.validation.constraints.Size;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
-
-/**
- * 瑙掕壊淇℃伅涓氬姟瀵硅薄 sys_role
- *
- * @author Michelle.Chung
- */
-
-@Data
-@NoArgsConstructor
-@EqualsAndHashCode(callSuper = true)
-@AutoMapper(target = SysRole.class, reverseConvertGenerate = false)
-public class SysRoleBo extends BaseEntity {
-
-    /**
-     * 瑙掕壊ID
-     */
-    @NotNull(message = "瑙掕壊ID涓嶈兘涓虹┖", groups = { EditGroup.class })
-    private Long roleId;
-
-    /**
-     * 瑙掕壊鍚嶇О
-     */
-    @NotBlank(message = "瑙掕壊鍚嶇О涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
-    @Size(min = 0, max = 30, message = "瑙掕壊鍚嶇О闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
-    private String roleName;
-
-    /**
-     * 瑙掕壊鏉冮檺瀛楃涓�
-     */
-    @NotBlank(message = "瑙掕壊鏉冮檺瀛楃涓蹭笉鑳戒负绌�", groups = { AddGroup.class, EditGroup.class })
-    @Size(min = 0, max = 100, message = "鏉冮檺瀛楃闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
-    private String roleKey;
-
-    /**
-     * 鏄剧ず椤哄簭
-     */
-    @NotNull(message = "鏄剧ず椤哄簭涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
-    private Integer roleSort;
-
-    /**
-     * 鏁版嵁鑼冨洿锛�1锛氬叏閮ㄦ暟鎹潈闄� 2锛氳嚜瀹氭暟鎹潈闄� 3锛氭湰閮ㄩ棬鏁版嵁鏉冮檺 4锛氭湰閮ㄩ棬鍙婁互涓嬫暟鎹潈闄愶級
-     */
-    private String dataScope;
-
-    /**
-     * 鑿滃崟鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�
-     */
-    private Boolean menuCheckStrictly;
-
-    /**
-     * 閮ㄩ棬鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�
-     */
-    private Boolean deptCheckStrictly;
-
-    /**
-     * 瑙掕壊鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    private String status;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-    /**
-     * 鑿滃崟缁�
-     */
-    private Long[] menuIds;
-
-    /**
-     * 閮ㄩ棬缁勶紙鏁版嵁鏉冮檺锛�
-     */
-    private Long[] deptIds;
-
-    public SysRoleBo(Long roleId) {
-        this.roleId = roleId;
-    }
-
-    public boolean isSuperAdmin() {
-        return UserConstants.SUPER_ADMIN_ID.equals(this.roleId);
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysTenantBo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysTenantBo.java
deleted file mode 100644
index 8ccaf45..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysTenantBo.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package com.ruoyi.system.domain.bo;
-
-import com.ruoyi.common.core.validate.AddGroup;
-import com.ruoyi.common.core.validate.EditGroup;
-import com.ruoyi.system.domain.SysTenant;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import jakarta.validation.constraints.*;
-
-import java.util.Date;
-
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-
-/**
- * 绉熸埛涓氬姟瀵硅薄 sys_tenant
- *
- * @author Michelle.Chung
- */
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@AutoMapper(target = SysTenant.class, reverseConvertGenerate = false)
-public class SysTenantBo extends BaseEntity {
-
-    /**
-     * id
-     */
-    @NotNull(message = "id涓嶈兘涓虹┖", groups = { EditGroup.class })
-    private Long id;
-
-    /**
-     * 绉熸埛缂栧彿
-     */
-    private String tenantId;
-
-    /**
-     * 鑱旂郴浜�
-     */
-    @NotBlank(message = "鑱旂郴浜轰笉鑳戒负绌�", groups = { AddGroup.class, EditGroup.class })
-    private String contactUserName;
-
-    /**
-     * 鑱旂郴鐢佃瘽
-     */
-    @NotBlank(message = "鑱旂郴鐢佃瘽涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
-    private String contactPhone;
-
-    /**
-     * 浼佷笟鍚嶇О
-     */
-    @NotBlank(message = "浼佷笟鍚嶇О涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
-    private String companyName;
-
-    /**
-     * 鐢ㄦ埛鍚嶏紙鍒涘缓绯荤粺鐢ㄦ埛锛�
-     */
-    @NotBlank(message = "鐢ㄦ埛鍚嶄笉鑳戒负绌�", groups = { AddGroup.class })
-    private String username;
-
-    /**
-     * 瀵嗙爜锛堝垱寤虹郴缁熺敤鎴凤級
-     */
-    @NotBlank(message = "瀵嗙爜涓嶈兘涓虹┖", groups = { AddGroup.class })
-    private String password;
-
-    /**
-     * 缁熶竴绀句細淇$敤浠g爜
-     */
-    private String licenseNumber;
-
-    /**
-     * 鍦板潃
-     */
-    private String address;
-
-    /**
-     * 鍩熷悕
-     */
-    private String domain;
-
-    /**
-     * 浼佷笟绠�浠�
-     */
-    private String intro;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-    /**
-     * 绉熸埛濂楅缂栧彿
-     */
-    @NotNull(message = "绉熸埛濂楅涓嶈兘涓虹┖", groups = { AddGroup.class })
-    private Long packageId;
-
-    /**
-     * 杩囨湡鏃堕棿
-     */
-    private Date expireTime;
-
-    /**
-     * 鐢ㄦ埛鏁伴噺锛�-1涓嶉檺鍒讹級
-     */
-    private Long accountCount;
-
-    /**
-     * 绉熸埛鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    private String status;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysTenantPackageBo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysTenantPackageBo.java
deleted file mode 100644
index c91a7c6..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysTenantPackageBo.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.ruoyi.system.domain.bo;
-
-import com.ruoyi.common.core.validate.AddGroup;
-import com.ruoyi.common.core.validate.EditGroup;
-import com.ruoyi.system.domain.SysTenantPackage;
-import io.github.linpeilie.annotations.AutoMapper;
-import io.github.linpeilie.annotations.AutoMapping;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import jakarta.validation.constraints.*;
-
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-
-/**
- * 绉熸埛濂楅涓氬姟瀵硅薄 sys_tenant_package
- *
- * @author Michelle.Chung
- */
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@AutoMapper(target = SysTenantPackage.class, reverseConvertGenerate = false)
-public class SysTenantPackageBo extends BaseEntity {
-
-    /**
-     * 绉熸埛濂楅id
-     */
-    @NotNull(message = "绉熸埛濂楅id涓嶈兘涓虹┖", groups = { EditGroup.class })
-    private Long packageId;
-
-    /**
-     * 濂楅鍚嶇О
-     */
-    @NotBlank(message = "濂楅鍚嶇О涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
-    private String packageName;
-
-    /**
-     * 鍏宠仈鑿滃崟id
-     */
-    @AutoMapping(target = "menuIds", expression = "java(com.ruoyi.common.core.utils.StringUtils.join(source.getMenuIds(), \",\"))")
-    private Long[] menuIds;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-    /**
-     * 鑿滃崟鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�
-     */
-    private Boolean menuCheckStrictly;
-
-    /**
-     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    private String status;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysUserBo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysUserBo.java
deleted file mode 100644
index c2a3309..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysUserBo.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package com.ruoyi.system.domain.bo;
-
-import com.ruoyi.common.core.constant.UserConstants;
-import com.ruoyi.common.core.xss.Xss;
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-import com.ruoyi.common.sensitive.annotation.Sensitive;
-import com.ruoyi.common.sensitive.core.SensitiveStrategy;
-import com.ruoyi.system.domain.SysUser;
-import io.github.linpeilie.annotations.AutoMapper;
-import jakarta.validation.constraints.Email;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import jakarta.validation.constraints.Size;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
-
-import java.util.Date;
-
-/**
- * 鐢ㄦ埛淇℃伅涓氬姟瀵硅薄 sys_user
- *
- * @author Michelle.Chung
- */
-
-@Data
-@NoArgsConstructor
-@EqualsAndHashCode(callSuper = true)
-@AutoMapper(target = SysUser.class, reverseConvertGenerate = false)
-public class SysUserBo extends BaseEntity {
-
-    /**
-     * 鐢ㄦ埛ID
-     */
-    private Long userId;
-
-    /**
-     * 閮ㄩ棬ID
-     */
-    private Long deptId;
-
-    /**
-     * 鐢ㄦ埛璐﹀彿
-     */
-    @Xss(message = "鐢ㄦ埛璐﹀彿涓嶈兘鍖呭惈鑴氭湰瀛楃")
-    @NotBlank(message = "鐢ㄦ埛璐﹀彿涓嶈兘涓虹┖")
-    @Size(min = 0, max = 30, message = "鐢ㄦ埛璐﹀彿闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
-    private String userName;
-
-    /**
-     * 鐢ㄦ埛鏄电О
-     */
-    @Xss(message = "鐢ㄦ埛鏄电О涓嶈兘鍖呭惈鑴氭湰瀛楃")
-    @Size(min = 0, max = 30, message = "鐢ㄦ埛鏄电О闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
-    private String nickName;
-
-    /**
-     * 鐢ㄦ埛绫诲瀷锛坰ys_user绯荤粺鐢ㄦ埛锛�
-     */
-    private String userType;
-
-    /**
-     * 鐢ㄦ埛閭
-     */
-    @Sensitive(strategy = SensitiveStrategy.EMAIL)
-    @Email(message = "閭鏍煎紡涓嶆纭�")
-    @Size(min = 0, max = 50, message = "閭闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
-    private String email;
-
-    /**
-     * 鎵嬫満鍙风爜
-     */
-    @Sensitive(strategy = SensitiveStrategy.PHONE)
-    private String phonenumber;
-
-    /**
-     * 鐢ㄦ埛鎬у埆锛�0鐢� 1濂� 2鏈煡锛�
-     */
-    private String sex;
-
-    /**
-     * 澶村儚鍦板潃
-     */
-    private Long avatar;
-
-    /**
-     * 瀵嗙爜
-     */
-    private String password;
-
-    /**
-     * 甯愬彿鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    private String status;
-
-    /**
-     * 鏈�鍚庣櫥褰旾P
-     */
-    private String loginIp;
-
-    /**
-     * 鏈�鍚庣櫥褰曟椂闂�
-     */
-    private Date loginDate;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-    /**
-     * 瑙掕壊缁�
-     */
-    @Size(min = 1, message = "鐢ㄦ埛瑙掕壊涓嶈兘涓虹┖")
-    private Long[] roleIds;
-
-    /**
-     * 宀椾綅缁�
-     */
-    private Long[] postIds;
-
-    /**
-     * 鏁版嵁鏉冮檺 褰撳墠瑙掕壊ID
-     */
-    private Long roleId;
-
-    public SysUserBo(Long userId) {
-        this.userId = userId;
-    }
-
-    public boolean isSuperAdmin() {
-        return UserConstants.SUPER_ADMIN_ID.equals(this.userId);
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysUserProfileBo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysUserProfileBo.java
deleted file mode 100644
index bfa7862..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysUserProfileBo.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.ruoyi.system.domain.bo;
-
-import com.ruoyi.common.core.xss.Xss;
-import com.ruoyi.common.mybatis.core.domain.BaseEntity;
-import com.ruoyi.common.sensitive.annotation.Sensitive;
-import com.ruoyi.common.sensitive.core.SensitiveStrategy;
-import jakarta.validation.constraints.Email;
-import jakarta.validation.constraints.Size;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
-
-/**
- * 涓汉淇℃伅涓氬姟澶勭悊
- *
- * @author Michelle.Chung
- */
-
-@Data
-@NoArgsConstructor
-@EqualsAndHashCode(callSuper = true)
-public class SysUserProfileBo extends BaseEntity {
-
-    /**
-     * 鐢ㄦ埛ID
-     */
-    private Long userId;
-
-    /**
-     * 鐢ㄦ埛鏄电О
-     */
-    @Xss(message = "鐢ㄦ埛鏄电О涓嶈兘鍖呭惈鑴氭湰瀛楃")
-    @Size(min = 0, max = 30, message = "鐢ㄦ埛鏄电О闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
-    private String nickName;
-
-    /**
-     * 鐢ㄦ埛閭
-     */
-    @Sensitive(strategy = SensitiveStrategy.EMAIL)
-    @Email(message = "閭鏍煎紡涓嶆纭�")
-    @Size(min = 0, max = 50, message = "閭闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
-    private String email;
-
-    /**
-     * 鎵嬫満鍙风爜
-     */
-    @Sensitive(strategy = SensitiveStrategy.PHONE)
-    private String phonenumber;
-
-    /**
-     * 鐢ㄦ埛鎬у埆锛�0鐢� 1濂� 2鏈煡锛�
-     */
-    private String sex;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/AvatarVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/AvatarVo.java
deleted file mode 100644
index 7a2bb16..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/AvatarVo.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import lombok.Data;
-
-/**
- * 鐢ㄦ埛澶村儚淇℃伅
- *
- * @author Michelle.Chung
- */
-@Data
-public class AvatarVo {
-
-    /**
-     * 澶村儚鍦板潃
-     */
-    private String imgUrl;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/CacheListInfoVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/CacheListInfoVo.java
deleted file mode 100644
index a8773a4..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/CacheListInfoVo.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import lombok.Data;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
-/**
- * 缂撳瓨鐩戞帶鍒楄〃淇℃伅
- *
- * @author Michelle.Chung
- */
-@Data
-public class CacheListInfoVo {
-
-    private Properties info;
-
-    private Long dbSize;
-
-    private List<Map<String, String>> commandStats;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/DeptTreeSelectVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/DeptTreeSelectVo.java
deleted file mode 100644
index 14c00f4..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/DeptTreeSelectVo.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import cn.hutool.core.lang.tree.Tree;
-import lombok.Data;
-
-import java.util.List;
-
-/**
- * 瑙掕壊閮ㄩ棬鍒楄〃鏍戜俊鎭�
- *
- * @author Michelle.Chung
- */
-@Data
-public class DeptTreeSelectVo {
-
-    /**
-     * 閫変腑閮ㄩ棬鍒楄〃
-     */
-    private List<Long> checkedKeys;
-
-    /**
-     * 涓嬫媺鏍戠粨鏋勫垪琛�
-     */
-    private List<Tree<Long>> depts;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MenuTreeSelectVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MenuTreeSelectVo.java
deleted file mode 100644
index 2ddce77..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MenuTreeSelectVo.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import cn.hutool.core.lang.tree.Tree;
-import lombok.Data;
-
-import java.util.List;
-
-/**
- * 瑙掕壊鑿滃崟鍒楄〃鏍戜俊鎭�
- *
- * @author Michelle.Chung
- */
-@Data
-public class MenuTreeSelectVo {
-
-    /**
-     * 閫変腑鑿滃崟鍒楄〃
-     */
-    private List<Long> checkedKeys;
-
-    /**
-     * 鑿滃崟涓嬫媺鏍戠粨鏋勫垪琛�
-     */
-    private List<Tree<Long>> menus;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MetaVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MetaVo.java
deleted file mode 100644
index a8606f3..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MetaVo.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import com.ruoyi.common.core.utils.StringUtils;
-import lombok.Data;
-
-/**
- * 璺敱鏄剧ず淇℃伅
- *
- * @author ruoyi
- */
-
-@Data
-public class MetaVo {
-
-    /**
-     * 璁剧疆璇ヨ矾鐢卞湪渚ц竟鏍忓拰闈㈠寘灞戜腑灞曠ず鐨勫悕瀛�
-     */
-    private String title;
-
-    /**
-     * 璁剧疆璇ヨ矾鐢辩殑鍥炬爣锛屽搴旇矾寰剆rc/assets/icons/svg
-     */
-    private String icon;
-
-    /**
-     * 璁剧疆涓簍rue锛屽垯涓嶄細琚� <keep-alive>缂撳瓨
-     */
-    private boolean noCache;
-
-    /**
-     * 鍐呴摼鍦板潃锛坔ttp(s)://寮�澶达級
-     */
-    private String link;
-
-    public MetaVo(String title, String icon) {
-        this.title = title;
-        this.icon = icon;
-    }
-
-    public MetaVo(String title, String icon, boolean noCache) {
-        this.title = title;
-        this.icon = icon;
-        this.noCache = noCache;
-    }
-
-    public MetaVo(String title, String icon, String link) {
-        this.title = title;
-        this.icon = icon;
-        this.link = link;
-    }
-
-    public MetaVo(String title, String icon, boolean noCache, String link) {
-        this.title = title;
-        this.icon = icon;
-        this.noCache = noCache;
-        if (StringUtils.ishttp(link)) {
-            this.link = link;
-        }
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/ProfileVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/ProfileVo.java
deleted file mode 100644
index a7f557c..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/ProfileVo.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import lombok.Data;
-
-/**
- * 鐢ㄦ埛涓汉淇℃伅
- *
- * @author Michelle.Chung
- */
-@Data
-public class ProfileVo {
-
-    /**
-     * 鐢ㄦ埛淇℃伅
-     */
-    private SysUserVo user;
-
-    /**
-     * 鐢ㄦ埛鎵�灞炶鑹茬粍
-     */
-    private String roleGroup;
-
-    /**
-     * 鐢ㄦ埛鎵�灞炲矖浣嶇粍
-     */
-    private String postGroup;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/RouterVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/RouterVo.java
deleted file mode 100644
index 8351f7c..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/RouterVo.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import lombok.Data;
-
-import java.util.List;
-
-/**
- * 璺敱閰嶇疆淇℃伅
- *
- * @author Lion Li
- */
-@Data
-@JsonInclude(JsonInclude.Include.NON_EMPTY)
-public class RouterVo {
-
-    /**
-     * 璺敱鍚嶅瓧
-     */
-    private String name;
-
-    /**
-     * 璺敱鍦板潃
-     */
-    private String path;
-
-    /**
-     * 鏄惁闅愯棌璺敱锛屽綋璁剧疆 true 鐨勬椂鍊欒璺敱涓嶄細鍐嶄晶杈规爮鍑虹幇
-     */
-    private boolean hidden;
-
-    /**
-     * 閲嶅畾鍚戝湴鍧�锛屽綋璁剧疆 noRedirect 鐨勬椂鍊欒璺敱鍦ㄩ潰鍖呭睉瀵艰埅涓笉鍙鐐瑰嚮
-     */
-    private String redirect;
-
-    /**
-     * 缁勪欢鍦板潃
-     */
-    private String component;
-
-    /**
-     * 璺敱鍙傛暟锛氬 {"id": 1, "name": "ry"}
-     */
-    private String query;
-
-    /**
-     * 褰撲綘涓�涓矾鐢变笅闈㈢殑 children 澹版槑鐨勮矾鐢卞ぇ浜�1涓椂锛岃嚜鍔ㄤ細鍙樻垚宓屽鐨勬ā寮�--濡傜粍浠堕〉闈�
-     */
-    private Boolean alwaysShow;
-
-    /**
-     * 鍏朵粬鍏冪礌
-     */
-    private MetaVo meta;
-
-    /**
-     * 瀛愯矾鐢�
-     */
-    private List<RouterVo> children;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysConfigVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysConfigVo.java
deleted file mode 100644
index 0edaa84..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysConfigVo.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.alibaba.excel.annotation.ExcelProperty;
-import com.ruoyi.common.excel.annotation.ExcelDictFormat;
-import com.ruoyi.common.excel.convert.ExcelDictConvert;
-import com.ruoyi.system.domain.SysConfig;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-
-
-/**
- * 鍙傛暟閰嶇疆瑙嗗浘瀵硅薄 sys_config
- *
- * @author Michelle.Chung
- */
-@Data
-@ExcelIgnoreUnannotated
-@AutoMapper(target = SysConfig.class)
-public class SysConfigVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 鍙傛暟涓婚敭
-     */
-    @ExcelProperty(value = "鍙傛暟涓婚敭")
-    private Long configId;
-
-    /**
-     * 鍙傛暟鍚嶇О
-     */
-    @ExcelProperty(value = "鍙傛暟鍚嶇О")
-    private String configName;
-
-    /**
-     * 鍙傛暟閿悕
-     */
-    @ExcelProperty(value = "鍙傛暟閿悕")
-    private String configKey;
-
-    /**
-     * 鍙傛暟閿��
-     */
-    @ExcelProperty(value = "鍙傛暟閿��")
-    private String configValue;
-
-    /**
-     * 绯荤粺鍐呯疆锛圷鏄� N鍚︼級
-     */
-    @ExcelProperty(value = "绯荤粺鍐呯疆", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(dictType = "sys_yes_no")
-    private String configType;
-
-    /**
-     * 澶囨敞
-     */
-    @ExcelProperty(value = "澶囨敞")
-    private String remark;
-
-    /**
-     * 鍒涘缓鏃堕棿
-     */
-    @ExcelProperty(value = "鍒涘缓鏃堕棿")
-    private Date createTime;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysDeptVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysDeptVo.java
deleted file mode 100644
index 71027e9..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysDeptVo.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.alibaba.excel.annotation.ExcelProperty;
-import com.ruoyi.common.excel.annotation.ExcelDictFormat;
-import com.ruoyi.common.excel.convert.ExcelDictConvert;
-import com.ruoyi.system.domain.SysDept;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-
-/**
- * 閮ㄩ棬瑙嗗浘瀵硅薄 sys_dept
- *
- * @author Michelle.Chung
- */
-@Data
-@ExcelIgnoreUnannotated
-@AutoMapper(target = SysDept.class)
-public class SysDeptVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 閮ㄩ棬id
-     */
-    @ExcelProperty(value = "閮ㄩ棬id")
-    private Long deptId;
-
-    /**
-     * 鐖堕儴闂╥d
-     */
-    private Long parentId;
-
-    /**
-     * 鐖堕儴闂ㄥ悕绉�
-     */
-    private String parentName;
-
-    /**
-     * 绁栫骇鍒楄〃
-     */
-    private String ancestors;
-
-    /**
-     * 閮ㄩ棬鍚嶇О
-     */
-    @ExcelProperty(value = "閮ㄩ棬鍚嶇О")
-    private String deptName;
-
-    /**
-     * 鏄剧ず椤哄簭
-     */
-    private Integer orderNum;
-
-    /**
-     * 璐熻矗浜�
-     */
-    @ExcelProperty(value = "璐熻矗浜�")
-    private String leader;
-
-    /**
-     * 鑱旂郴鐢佃瘽
-     */
-    @ExcelProperty(value = "鑱旂郴鐢佃瘽")
-    private String phone;
-
-    /**
-     * 閭
-     */
-    @ExcelProperty(value = "閭")
-    private String email;
-
-    /**
-     * 閮ㄩ棬鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    @ExcelProperty(value = "閮ㄩ棬鐘舵��", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(dictType = "sys_normal_disable")
-    private String status;
-
-    /**
-     * 鍒涘缓鏃堕棿
-     */
-    @ExcelProperty(value = "鍒涘缓鏃堕棿")
-    private Date createTime;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysDictDataVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysDictDataVo.java
deleted file mode 100644
index 3273076..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysDictDataVo.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.alibaba.excel.annotation.ExcelProperty;
-import com.ruoyi.common.excel.annotation.ExcelDictFormat;
-import com.ruoyi.common.excel.convert.ExcelDictConvert;
-import com.ruoyi.system.domain.SysDictData;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-
-
-/**
- * 瀛楀吀鏁版嵁瑙嗗浘瀵硅薄 sys_dict_data
- *
- * @author Michelle.Chung
- */
-@Data
-@ExcelIgnoreUnannotated
-@AutoMapper(target = SysDictData.class)
-public class SysDictDataVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 瀛楀吀缂栫爜
-     */
-    @ExcelProperty(value = "瀛楀吀缂栫爜")
-    private Long dictCode;
-
-    /**
-     * 瀛楀吀鎺掑簭
-     */
-    @ExcelProperty(value = "瀛楀吀鎺掑簭")
-    private Integer dictSort;
-
-    /**
-     * 瀛楀吀鏍囩
-     */
-    @ExcelProperty(value = "瀛楀吀鏍囩")
-    private String dictLabel;
-
-    /**
-     * 瀛楀吀閿��
-     */
-    @ExcelProperty(value = "瀛楀吀閿��")
-    private String dictValue;
-
-    /**
-     * 瀛楀吀绫诲瀷
-     */
-    @ExcelProperty(value = "瀛楀吀绫诲瀷")
-    private String dictType;
-
-    /**
-     * 鏍峰紡灞炴�э紙鍏朵粬鏍峰紡鎵╁睍锛�
-     */
-    private String cssClass;
-
-    /**
-     * 琛ㄦ牸鍥炴樉鏍峰紡
-     */
-    private String listClass;
-
-    /**
-     * 鏄惁榛樿锛圷鏄� N鍚︼級
-     */
-    @ExcelProperty(value = "鏄惁榛樿", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(dictType = "sys_yes_no")
-    private String isDefault;
-
-    /**
-     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    @ExcelProperty(value = "鐘舵��", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(dictType = "sys_normal_disable")
-    private String status;
-
-    /**
-     * 澶囨敞
-     */
-    @ExcelProperty(value = "澶囨敞")
-    private String remark;
-
-    /**
-     * 鍒涘缓鏃堕棿
-     */
-    @ExcelProperty(value = "鍒涘缓鏃堕棿")
-    private Date createTime;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysDictTypeVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysDictTypeVo.java
deleted file mode 100644
index fce48d9..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysDictTypeVo.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.alibaba.excel.annotation.ExcelProperty;
-import com.ruoyi.common.excel.annotation.ExcelDictFormat;
-import com.ruoyi.common.excel.convert.ExcelDictConvert;
-import com.ruoyi.system.domain.SysDictType;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-
-
-/**
- * 瀛楀吀绫诲瀷瑙嗗浘瀵硅薄 sys_dict_type
- *
- * @author Michelle.Chung
- */
-@Data
-@ExcelIgnoreUnannotated
-@AutoMapper(target = SysDictType.class)
-public class SysDictTypeVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 瀛楀吀涓婚敭
-     */
-    @ExcelProperty(value = "瀛楀吀涓婚敭")
-    private Long dictId;
-
-    /**
-     * 瀛楀吀鍚嶇О
-     */
-    @ExcelProperty(value = "瀛楀吀鍚嶇О")
-    private String dictName;
-
-    /**
-     * 瀛楀吀绫诲瀷
-     */
-    @ExcelProperty(value = "瀛楀吀绫诲瀷")
-    private String dictType;
-
-    /**
-     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    @ExcelProperty(value = "鐘舵��", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(dictType = "sys_normal_disable")
-    private String status;
-
-    /**
-     * 澶囨敞
-     */
-    @ExcelProperty(value = "澶囨敞")
-    private String remark;
-
-    /**
-     * 鍒涘缓鏃堕棿
-     */
-    @ExcelProperty(value = "鍒涘缓鏃堕棿")
-    private Date createTime;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysLogininforVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysLogininforVo.java
deleted file mode 100644
index a0fd89f..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysLogininforVo.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import java.util.Date;
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.alibaba.excel.annotation.ExcelProperty;
-import com.ruoyi.common.excel.annotation.ExcelDictFormat;
-import com.ruoyi.common.excel.convert.ExcelDictConvert;
-import com.ruoyi.system.domain.SysLogininfor;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-
-
-/**
- * 绯荤粺璁块棶璁板綍瑙嗗浘瀵硅薄 sys_logininfor
- *
- * @author Michelle.Chung
- * @date 2023-02-07
- */
-@Data
-@ExcelIgnoreUnannotated
-@AutoMapper(target = SysLogininfor.class)
-public class SysLogininforVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 璁块棶ID
-     */
-    @ExcelProperty(value = "搴忓彿")
-    private Long infoId;
-
-    /**
-     * 绉熸埛缂栧彿
-     */
-    private String tenantId;
-
-    /**
-     * 鐢ㄦ埛璐﹀彿
-     */
-    @ExcelProperty(value = "鐢ㄦ埛璐﹀彿")
-    private String userName;
-
-    /**
-     * 鐧诲綍鐘舵�侊紙0鎴愬姛 1澶辫触锛�
-     */
-    @ExcelProperty(value = "鐧诲綍鐘舵��", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(dictType = "sys_common_status")
-    private String status;
-
-    /**
-     * 鐧诲綍IP鍦板潃
-     */
-    @ExcelProperty(value = "鐧诲綍鍦板潃")
-    private String ipaddr;
-
-    /**
-     * 鐧诲綍鍦扮偣
-     */
-    @ExcelProperty(value = "鐧诲綍鍦扮偣")
-    private String loginLocation;
-
-    /**
-     * 娴忚鍣ㄧ被鍨�
-     */
-    @ExcelProperty(value = "娴忚鍣�")
-    private String browser;
-
-    /**
-     * 鎿嶄綔绯荤粺
-     */
-    @ExcelProperty(value = "鎿嶄綔绯荤粺")
-    private String os;
-
-
-    /**
-     * 鎻愮ず娑堟伅
-     */
-    @ExcelProperty(value = "鎻愮ず娑堟伅")
-    private String msg;
-
-    /**
-     * 璁块棶鏃堕棿
-     */
-    @ExcelProperty(value = "璁块棶鏃堕棿")
-    private Date loginTime;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysMenuVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysMenuVo.java
deleted file mode 100644
index 0131c50..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysMenuVo.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import com.ruoyi.system.domain.SysMenu;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-
-/**
- * 鑿滃崟鏉冮檺瑙嗗浘瀵硅薄 sys_menu
- *
- * @author Michelle.Chung
- */
-@Data
-@AutoMapper(target = SysMenu.class)
-public class SysMenuVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 鑿滃崟ID
-     */
-    private Long menuId;
-
-    /**
-     * 鑿滃崟鍚嶇О
-     */
-    private String menuName;
-
-    /**
-     * 鐖惰彍鍗旾D
-     */
-    private Long parentId;
-
-    /**
-     * 鏄剧ず椤哄簭
-     */
-    private Integer orderNum;
-
-    /**
-     * 璺敱鍦板潃
-     */
-    private String path;
-
-    /**
-     * 缁勪欢璺緞
-     */
-    private String component;
-
-    /**
-     * 璺敱鍙傛暟
-     */
-    private String queryParam;
-
-    /**
-     * 鏄惁涓哄閾撅紙0鏄� 1鍚︼級
-     */
-    private String isFrame;
-
-    /**
-     * 鏄惁缂撳瓨锛�0缂撳瓨 1涓嶇紦瀛橈級
-     */
-    private String isCache;
-
-    /**
-     * 鑿滃崟绫诲瀷锛圡鐩綍 C鑿滃崟 F鎸夐挳锛�
-     */
-    private String menuType;
-
-    /**
-     * 鏄剧ず鐘舵�侊紙0鏄剧ず 1闅愯棌锛�
-     */
-    private String visible;
-
-    /**
-     * 鑿滃崟鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    private String status;
-
-    /**
-     * 鏉冮檺鏍囪瘑
-     */
-    private String perms;
-
-    /**
-     * 鑿滃崟鍥炬爣
-     */
-    private String icon;
-
-    /**
-     * 鍒涘缓閮ㄩ棬
-     */
-    private Long createDept;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-    /**
-     * 鍒涘缓鏃堕棿
-     */
-    private Date createTime;
-
-    /**
-     * 瀛愯彍鍗�
-     */
-    private List<SysMenuVo> children = new ArrayList<>();
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysNoticeVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysNoticeVo.java
deleted file mode 100644
index 57a20d0..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysNoticeVo.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import com.ruoyi.common.translation.annotation.Translation;
-import com.ruoyi.common.translation.constant.TransConstant;
-import com.ruoyi.system.domain.SysNotice;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-
-
-
-/**
- * 閫氱煡鍏憡瑙嗗浘瀵硅薄 sys_notice
- *
- * @author Michelle.Chung
- */
-@Data
-@AutoMapper(target = SysNotice.class)
-public class SysNoticeVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 鍏憡ID
-     */
-    private Long noticeId;
-
-    /**
-     * 鍏憡鏍囬
-     */
-    private String noticeTitle;
-
-    /**
-     * 鍏憡绫诲瀷锛�1閫氱煡 2鍏憡锛�
-     */
-    private String noticeType;
-
-    /**
-     * 鍏憡鍐呭
-     */
-    private String noticeContent;
-
-    /**
-     * 鍏憡鐘舵�侊紙0姝e父 1鍏抽棴锛�
-     */
-    private String status;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-    /**
-     * 鍒涘缓鑰�
-     */
-    private Long createBy;
-
-    /**
-     * 鍒涘缓浜哄悕绉�
-     */
-    @Translation(type = TransConstant.USER_ID_TO_NAME, mapper = "createBy")
-    private String createByName;
-
-    /**
-     * 鍒涘缓鏃堕棿
-     */
-    private Date createTime;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOperLogVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOperLogVo.java
deleted file mode 100644
index 3c67c73..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOperLogVo.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.alibaba.excel.annotation.ExcelProperty;
-import com.ruoyi.common.excel.annotation.ExcelDictFormat;
-import com.ruoyi.common.excel.convert.ExcelDictConvert;
-import com.ruoyi.system.domain.SysOperLog;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-
-
-/**
- * 鎿嶄綔鏃ュ織璁板綍瑙嗗浘瀵硅薄 sys_oper_log
- *
- * @author Michelle.Chung
- * @date 2023-02-07
- */
-@Data
-@ExcelIgnoreUnannotated
-@AutoMapper(target = SysOperLog.class)
-public class SysOperLogVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 鏃ュ織涓婚敭
-     */
-    @ExcelProperty(value = "鏃ュ織涓婚敭")
-    private Long operId;
-
-    /**
-     * 绉熸埛缂栧彿
-     */
-    private String tenantId;
-
-    /**
-     * 妯″潡鏍囬
-     */
-    @ExcelProperty(value = "鎿嶄綔妯″潡")
-    private String title;
-
-    /**
-     * 涓氬姟绫诲瀷锛�0鍏跺畠 1鏂板 2淇敼 3鍒犻櫎锛�
-     */
-    @ExcelProperty(value = "涓氬姟绫诲瀷", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(dictType = "sys_oper_type")
-    private Integer businessType;
-
-    /**
-     * 涓氬姟绫诲瀷鏁扮粍
-     */
-    private Integer[] businessTypes;
-
-    /**
-     * 鏂规硶鍚嶇О
-     */
-    @ExcelProperty(value = "璇锋眰鏂规硶")
-    private String method;
-
-    /**
-     * 璇锋眰鏂瑰紡
-     */
-    @ExcelProperty(value = "璇锋眰鏂瑰紡")
-    private String requestMethod;
-
-    /**
-     * 鎿嶄綔绫诲埆锛�0鍏跺畠 1鍚庡彴鐢ㄦ埛 2鎵嬫満绔敤鎴凤級
-     */
-    @ExcelProperty(value = "鎿嶄綔绫诲埆", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(readConverterExp = "0=鍏跺畠,1=鍚庡彴鐢ㄦ埛,2=鎵嬫満绔敤鎴�")
-    private Integer operatorType;
-
-    /**
-     * 鎿嶄綔浜哄憳
-     */
-    @ExcelProperty(value = "鎿嶄綔浜哄憳")
-    private String operName;
-
-    /**
-     * 閮ㄩ棬鍚嶇О
-     */
-    @ExcelProperty(value = "閮ㄩ棬鍚嶇О")
-    private String deptName;
-
-    /**
-     * 璇锋眰URL
-     */
-    @ExcelProperty(value = "璇锋眰鍦板潃")
-    private String operUrl;
-
-    /**
-     * 涓绘満鍦板潃
-     */
-    @ExcelProperty(value = "鎿嶄綔鍦板潃")
-    private String operIp;
-
-    /**
-     * 鎿嶄綔鍦扮偣
-     */
-    @ExcelProperty(value = "鎿嶄綔鍦扮偣")
-    private String operLocation;
-
-    /**
-     * 璇锋眰鍙傛暟
-     */
-    @ExcelProperty(value = "璇锋眰鍙傛暟")
-    private String operParam;
-
-    /**
-     * 杩斿洖鍙傛暟
-     */
-    @ExcelProperty(value = "杩斿洖鍙傛暟")
-    private String jsonResult;
-
-    /**
-     * 鎿嶄綔鐘舵�侊紙0姝e父 1寮傚父锛�
-     */
-    @ExcelProperty(value = "鐘舵��", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(dictType = "sys_common_status")
-    private Integer status;
-
-    /**
-     * 閿欒娑堟伅
-     */
-    @ExcelProperty(value = "閿欒娑堟伅")
-    private String errorMsg;
-
-    /**
-     * 鎿嶄綔鏃堕棿
-     */
-    @ExcelProperty(value = "鎿嶄綔鏃堕棿")
-    private Date operTime;
-
-    /**
-     * 娑堣�楁椂闂�
-     */
-    @ExcelProperty(value = "娑堣�楁椂闂�")
-    private Long costTime;
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOssConfigVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOssConfigVo.java
deleted file mode 100644
index 11ef727..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOssConfigVo.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.ruoyi.system.domain.SysOssConfig;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-
-/**
- * 瀵硅薄瀛樺偍閰嶇疆瑙嗗浘瀵硅薄 sys_oss_config
- *
- * @author Lion Li
- * @author 瀛よ垷鐑熼洦
- * @date 2021-08-13
- */
-@Data
-@ExcelIgnoreUnannotated
-@AutoMapper(target = SysOssConfig.class)
-public class SysOssConfigVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 涓诲缓
-     */
-    private Long ossConfigId;
-
-    /**
-     * 閰嶇疆key
-     */
-    private String configKey;
-
-    /**
-     * accessKey
-     */
-    private String accessKey;
-
-    /**
-     * 绉橀挜
-     */
-    private String secretKey;
-
-    /**
-     * 妗跺悕绉�
-     */
-    private String bucketName;
-
-    /**
-     * 鍓嶇紑
-     */
-    private String prefix;
-
-    /**
-     * 璁块棶绔欑偣
-     */
-    private String endpoint;
-
-    /**
-     * 鑷畾涔夊煙鍚�
-     */
-    private String domain;
-
-    /**
-     * 鏄惁https锛圷=鏄�,N=鍚︼級
-     */
-    private String isHttps;
-
-    /**
-     * 鍩�
-     */
-    private String region;
-
-    /**
-     * 鏄惁榛樿锛�0=鏄�,1=鍚︼級
-     */
-    private String status;
-
-    /**
-     * 鎵╁睍瀛楁
-     */
-    private String ext1;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-    /**
-     * 妗舵潈闄愮被鍨�(0private 1public 2custom)
-     */
-    private String accessPolicy;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOssUploadVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOssUploadVo.java
deleted file mode 100644
index c7630f0..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOssUploadVo.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import lombok.Data;
-
-/**
- * 涓婁紶瀵硅薄淇℃伅
- *
- * @author Michelle.Chung
- */
-@Data
-public class SysOssUploadVo {
-
-    /**
-     * URL鍦板潃
-     */
-    private String url;
-
-    /**
-     * 鏂囦欢鍚�
-     */
-    private String fileName;
-
-    /**
-     * 瀵硅薄瀛樺偍涓婚敭
-     */
-    private String ossId;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOssVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOssVo.java
deleted file mode 100644
index 3bf95ac..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOssVo.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import com.ruoyi.common.translation.annotation.Translation;
-import com.ruoyi.common.translation.constant.TransConstant;
-import com.ruoyi.system.domain.SysOss;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-
-/**
- * OSS瀵硅薄瀛樺偍瑙嗗浘瀵硅薄 sys_oss
- *
- * @author Lion Li
- */
-@Data
-@AutoMapper(target = SysOss.class)
-public class SysOssVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 瀵硅薄瀛樺偍涓婚敭
-     */
-    private Long ossId;
-
-    /**
-     * 鏂囦欢鍚�
-     */
-    private String fileName;
-
-    /**
-     * 鍘熷悕
-     */
-    private String originalName;
-
-    /**
-     * 鏂囦欢鍚庣紑鍚�
-     */
-    private String fileSuffix;
-
-    /**
-     * URL鍦板潃
-     */
-    private String url;
-
-    /**
-     * 鍒涘缓鏃堕棿
-     */
-    private Date createTime;
-
-    /**
-     * 涓婁紶浜�
-     */
-    private Long createBy;
-
-    /**
-     * 涓婁紶浜哄悕绉�
-     */
-    @Translation(type = TransConstant.USER_ID_TO_NAME, mapper = "createBy")
-    private String createByName;
-
-    /**
-     * 鏈嶅姟鍟�
-     */
-    private String service;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysPostVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysPostVo.java
deleted file mode 100644
index 2c9f5e7..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysPostVo.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.alibaba.excel.annotation.ExcelProperty;
-import com.ruoyi.common.excel.annotation.ExcelDictFormat;
-import com.ruoyi.common.excel.convert.ExcelDictConvert;
-import com.ruoyi.system.domain.SysPost;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-
-
-
-/**
- * 宀椾綅淇℃伅瑙嗗浘瀵硅薄 sys_post
- *
- * @author Michelle.Chung
- */
-@Data
-@ExcelIgnoreUnannotated
-@AutoMapper(target = SysPost.class)
-public class SysPostVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 宀椾綅ID
-     */
-    @ExcelProperty(value = "宀椾綅搴忓彿")
-    private Long postId;
-
-    /**
-     * 宀椾綅缂栫爜
-     */
-    @ExcelProperty(value = "宀椾綅缂栫爜")
-    private String postCode;
-
-    /**
-     * 宀椾綅鍚嶇О
-     */
-    @ExcelProperty(value = "宀椾綅鍚嶇О")
-    private String postName;
-
-    /**
-     * 鏄剧ず椤哄簭
-     */
-    @ExcelProperty(value = "宀椾綅鎺掑簭")
-    private Integer postSort;
-
-    /**
-     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    @ExcelProperty(value = "鐘舵��", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(dictType = "sys_normal_disable")
-    private String status;
-
-    /**
-     * 澶囨敞
-     */
-    @ExcelProperty(value = "澶囨敞")
-    private String remark;
-
-    /**
-     * 鍒涘缓鏃堕棿
-     */
-    @ExcelProperty(value = "鍒涘缓鏃堕棿")
-    private Date createTime;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysRoleVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysRoleVo.java
deleted file mode 100644
index 06f97a4..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysRoleVo.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.alibaba.excel.annotation.ExcelProperty;
-import com.ruoyi.common.core.constant.UserConstants;
-import com.ruoyi.common.excel.annotation.ExcelDictFormat;
-import com.ruoyi.common.excel.convert.ExcelDictConvert;
-import com.ruoyi.system.domain.SysRole;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-
-/**
- * 瑙掕壊淇℃伅瑙嗗浘瀵硅薄 sys_role
- *
- * @author Michelle.Chung
- */
-@Data
-@ExcelIgnoreUnannotated
-@AutoMapper(target = SysRole.class)
-public class SysRoleVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 瑙掕壊ID
-     */
-    @ExcelProperty(value = "瑙掕壊搴忓彿")
-    private Long roleId;
-
-    /**
-     * 瑙掕壊鍚嶇О
-     */
-    @ExcelProperty(value = "瑙掕壊鍚嶇О")
-    private String roleName;
-
-    /**
-     * 瑙掕壊鏉冮檺瀛楃涓�
-     */
-    @ExcelProperty(value = "瑙掕壊鏉冮檺")
-    private String roleKey;
-
-    /**
-     * 鏄剧ず椤哄簭
-     */
-    @ExcelProperty(value = "瑙掕壊鎺掑簭")
-    private Integer roleSort;
-
-    /**
-     * 鏁版嵁鑼冨洿锛�1锛氬叏閮ㄦ暟鎹潈闄� 2锛氳嚜瀹氭暟鎹潈闄� 3锛氭湰閮ㄩ棬鏁版嵁鏉冮檺 4锛氭湰閮ㄩ棬鍙婁互涓嬫暟鎹潈闄愶級
-     */
-    @ExcelProperty(value = "鏁版嵁鑼冨洿", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(readConverterExp = "1=鎵�鏈夋暟鎹潈闄�,2=鑷畾涔夋暟鎹潈闄�,3=鏈儴闂ㄦ暟鎹潈闄�,4=鏈儴闂ㄥ強浠ヤ笅鏁版嵁鏉冮檺,5=浠呮湰浜烘暟鎹潈闄�")
-    private String dataScope;
-
-    /**
-     * 鑿滃崟鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�
-     */
-    @ExcelProperty(value = "鑿滃崟鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�")
-    private Boolean menuCheckStrictly;
-
-    /**
-     * 閮ㄩ棬鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�
-     */
-    @ExcelProperty(value = "閮ㄩ棬鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�")
-    private Boolean deptCheckStrictly;
-
-    /**
-     * 瑙掕壊鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    @ExcelProperty(value = "瑙掕壊鐘舵��", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(dictType = "sys_normal_disable")
-    private String status;
-
-    /**
-     * 澶囨敞
-     */
-    @ExcelProperty(value = "澶囨敞")
-    private String remark;
-
-    /**
-     * 鍒涘缓鏃堕棿
-     */
-    @ExcelProperty(value = "鍒涘缓鏃堕棿")
-    private Date createTime;
-
-    /**
-     * 鐢ㄦ埛鏄惁瀛樺湪姝よ鑹叉爣璇� 榛樿涓嶅瓨鍦�
-     */
-    private boolean flag = false;
-
-    public boolean isSuperAdmin() {
-        return UserConstants.SUPER_ADMIN_ID.equals(this.roleId);
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysTenantPackageVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysTenantPackageVo.java
deleted file mode 100644
index 3274ae5..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysTenantPackageVo.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.alibaba.excel.annotation.ExcelProperty;
-import com.ruoyi.common.excel.annotation.ExcelDictFormat;
-import com.ruoyi.common.excel.convert.ExcelDictConvert;
-import com.ruoyi.system.domain.SysTenantPackage;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-
-/**
- * 绉熸埛濂楅瑙嗗浘瀵硅薄 sys_tenant_package
- *
- * @author Michelle.Chung
- */
-@Data
-@ExcelIgnoreUnannotated
-@AutoMapper(target = SysTenantPackage.class)
-public class SysTenantPackageVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 绉熸埛濂楅id
-     */
-    @ExcelProperty(value = "绉熸埛濂楅id")
-    private Long packageId;
-
-    /**
-     * 濂楅鍚嶇О
-     */
-    @ExcelProperty(value = "濂楅鍚嶇О")
-    private String packageName;
-
-    /**
-     * 鍏宠仈鑿滃崟id
-     */
-    @ExcelProperty(value = "鍏宠仈鑿滃崟id")
-    private String menuIds;
-
-    /**
-     * 澶囨敞
-     */
-    @ExcelProperty(value = "澶囨敞")
-    private String remark;
-
-    /**
-     * 鑿滃崟鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�
-     */
-    @ExcelProperty(value = "鑿滃崟鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�")
-    private Boolean menuCheckStrictly;
-
-    /**
-     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    @ExcelProperty(value = "鐘舵��", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(readConverterExp = "0=姝e父,1=鍋滅敤")
-    private String status;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysTenantVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysTenantVo.java
deleted file mode 100644
index 656ee19..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysTenantVo.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import java.util.Date;
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.alibaba.excel.annotation.ExcelProperty;
-import com.ruoyi.common.excel.annotation.ExcelDictFormat;
-import com.ruoyi.common.excel.convert.ExcelDictConvert;
-import com.ruoyi.system.domain.SysTenant;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-
-/**
- * 绉熸埛瑙嗗浘瀵硅薄 sys_tenant
- *
- * @author Michelle.Chung
- */
-@Data
-@ExcelIgnoreUnannotated
-@AutoMapper(target = SysTenant.class)
-public class SysTenantVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * id
-     */
-    @ExcelProperty(value = "id")
-    private Long id;
-
-    /**
-     * 绉熸埛缂栧彿
-     */
-    @ExcelProperty(value = "绉熸埛缂栧彿")
-    private String tenantId;
-
-    /**
-     * 鑱旂郴浜�
-     */
-    @ExcelProperty(value = "鑱旂郴浜�")
-    private String contactUserName;
-
-    /**
-     * 鑱旂郴鐢佃瘽
-     */
-    @ExcelProperty(value = "鑱旂郴鐢佃瘽")
-    private String contactPhone;
-
-    /**
-     * 浼佷笟鍚嶇О
-     */
-    @ExcelProperty(value = "浼佷笟鍚嶇О")
-    private String companyName;
-
-    /**
-     * 缁熶竴绀句細淇$敤浠g爜
-     */
-    @ExcelProperty(value = "缁熶竴绀句細淇$敤浠g爜")
-    private String licenseNumber;
-
-    /**
-     * 鍦板潃
-     */
-    @ExcelProperty(value = "鍦板潃")
-    private String address;
-
-    /**
-     * 鍩熷悕
-     */
-    @ExcelProperty(value = "鍩熷悕")
-    private String domain;
-
-    /**
-     * 浼佷笟绠�浠�
-     */
-    @ExcelProperty(value = "浼佷笟绠�浠�")
-    private String intro;
-
-    /**
-     * 澶囨敞
-     */
-    @ExcelProperty(value = "澶囨敞")
-    private String remark;
-
-    /**
-     * 绉熸埛濂楅缂栧彿
-     */
-    @ExcelProperty(value = "绉熸埛濂楅缂栧彿")
-    private Long packageId;
-
-    /**
-     * 杩囨湡鏃堕棿
-     */
-    @ExcelProperty(value = "杩囨湡鏃堕棿")
-    private Date expireTime;
-
-    /**
-     * 鐢ㄦ埛鏁伴噺锛�-1涓嶉檺鍒讹級
-     */
-    @ExcelProperty(value = "鐢ㄦ埛鏁伴噺")
-    private Long accountCount;
-
-    /**
-     * 绉熸埛鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    @ExcelProperty(value = "绉熸埛鐘舵��", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(readConverterExp = "0=姝e父,1=鍋滅敤")
-    private String status;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserExportVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserExportVo.java
deleted file mode 100644
index 3135cf8..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserExportVo.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import com.alibaba.excel.annotation.ExcelProperty;
-import com.ruoyi.common.excel.annotation.ExcelDictFormat;
-import com.ruoyi.common.excel.convert.ExcelDictConvert;
-import io.github.linpeilie.annotations.AutoMapper;
-import io.github.linpeilie.annotations.ReverseAutoMapping;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-
-/**
- * 鐢ㄦ埛瀵硅薄瀵煎嚭VO
- *
- * @author Lion Li
- */
-
-@Data
-@NoArgsConstructor
-@AutoMapper(target = SysUserVo.class, convertGenerate = false)
-public class SysUserExportVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 鐢ㄦ埛ID
-     */
-    @ExcelProperty(value = "鐢ㄦ埛搴忓彿")
-    private Long userId;
-
-    /**
-     * 鐢ㄦ埛璐﹀彿
-     */
-    @ExcelProperty(value = "鐧诲綍鍚嶇О")
-    private String userName;
-
-    /**
-     * 鐢ㄦ埛鏄电О
-     */
-    @ExcelProperty(value = "鐢ㄦ埛鍚嶇О")
-    private String nickName;
-
-    /**
-     * 鐢ㄦ埛閭
-     */
-    @ExcelProperty(value = "鐢ㄦ埛閭")
-    private String email;
-
-    /**
-     * 鎵嬫満鍙风爜
-     */
-    @ExcelProperty(value = "鎵嬫満鍙风爜")
-    private String phonenumber;
-
-    /**
-     * 鐢ㄦ埛鎬у埆
-     */
-    @ExcelProperty(value = "鐢ㄦ埛鎬у埆", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(dictType = "sys_user_sex")
-    private String sex;
-
-    /**
-     * 甯愬彿鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    @ExcelProperty(value = "甯愬彿鐘舵��", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(dictType = "sys_normal_disable")
-    private String status;
-
-    /**
-     * 鏈�鍚庣櫥褰旾P
-     */
-    @ExcelProperty(value = "鏈�鍚庣櫥褰旾P")
-    private String loginIp;
-
-    /**
-     * 鏈�鍚庣櫥褰曟椂闂�
-     */
-    @ExcelProperty(value = "鏈�鍚庣櫥褰曟椂闂�")
-    private Date loginDate;
-
-    /**
-     * 閮ㄩ棬鍚嶇О
-     */
-    @ReverseAutoMapping(target = "deptName", source = "dept.deptName")
-    @ExcelProperty(value = "閮ㄩ棬鍚嶇О")
-    private String deptName;
-
-    /**
-     * 璐熻矗浜�
-     */
-    @ReverseAutoMapping(target = "leader", source = "dept.leader")
-    @ExcelProperty(value = "閮ㄩ棬璐熻矗浜�")
-    private String leader;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserImportVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserImportVo.java
deleted file mode 100644
index e38a8dd..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserImportVo.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import com.alibaba.excel.annotation.ExcelProperty;
-import com.ruoyi.common.excel.annotation.ExcelDictFormat;
-import com.ruoyi.common.excel.convert.ExcelDictConvert;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-/**
- * 鐢ㄦ埛瀵硅薄瀵煎叆VO
- *
- * @author Lion Li
- */
-
-@Data
-@NoArgsConstructor
-// @Accessors(chain = true) // 瀵煎叆涓嶅厑璁镐娇鐢� 浼氭壘涓嶅埌set鏂规硶
-public class SysUserImportVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 鐢ㄦ埛ID
-     */
-    @ExcelProperty(value = "鐢ㄦ埛搴忓彿")
-    private Long userId;
-
-    /**
-     * 閮ㄩ棬ID
-     */
-    @ExcelProperty(value = "閮ㄩ棬缂栧彿")
-    private Long deptId;
-
-    /**
-     * 鐢ㄦ埛璐﹀彿
-     */
-    @ExcelProperty(value = "鐧诲綍鍚嶇О")
-    private String userName;
-
-    /**
-     * 鐢ㄦ埛鏄电О
-     */
-    @ExcelProperty(value = "鐢ㄦ埛鍚嶇О")
-    private String nickName;
-
-    /**
-     * 鐢ㄦ埛閭
-     */
-    @ExcelProperty(value = "鐢ㄦ埛閭")
-    private String email;
-
-    /**
-     * 鎵嬫満鍙风爜
-     */
-    @ExcelProperty(value = "鎵嬫満鍙风爜")
-    private String phonenumber;
-
-    /**
-     * 鐢ㄦ埛鎬у埆
-     */
-    @ExcelProperty(value = "鐢ㄦ埛鎬у埆", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(dictType = "sys_user_sex")
-    private String sex;
-
-    /**
-     * 甯愬彿鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    @ExcelProperty(value = "甯愬彿鐘舵��", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(dictType = "sys_normal_disable")
-    private String status;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserInfoVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserInfoVo.java
deleted file mode 100644
index d675a08..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserInfoVo.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import lombok.Data;
-
-import java.util.List;
-
-/**
- * 鐢ㄦ埛淇℃伅
- *
- * @author Michelle.Chung
- */
-@Data
-public class SysUserInfoVo {
-
-    /**
-     * 鐢ㄦ埛淇℃伅
-     */
-    private SysUserVo user;
-
-    /**
-     * 瑙掕壊ID鍒楄〃
-     */
-    private List<Long> roleIds;
-
-    /**
-     * 瑙掕壊鍒楄〃
-     */
-    private List<SysRoleVo> roles;
-
-    /**
-     * 宀椾綅ID鍒楄〃
-     */
-    private List<Long> postIds;
-
-    /**
-     * 宀椾綅鍒楄〃
-     */
-    private List<SysPostVo> posts;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserVo.java
deleted file mode 100644
index 55c008a..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserVo.java
+++ /dev/null
@@ -1,137 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.ruoyi.common.translation.annotation.Translation;
-import com.ruoyi.common.translation.constant.TransConstant;
-import com.ruoyi.system.domain.SysUser;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-import java.util.List;
-
-
-/**
- * 鐢ㄦ埛淇℃伅瑙嗗浘瀵硅薄 sys_user
- *
- * @author Michelle.Chung
- */
-@Data
-@AutoMapper(target = SysUser.class)
-public class SysUserVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 鐢ㄦ埛ID
-     */
-    private Long userId;
-
-    /**
-     * 绉熸埛ID
-     */
-    private String tenantId;
-
-    /**
-     * 閮ㄩ棬ID
-     */
-    private Long deptId;
-
-    /**
-     * 鐢ㄦ埛璐﹀彿
-     */
-    private String userName;
-
-    /**
-     * 鐢ㄦ埛鏄电О
-     */
-    private String nickName;
-
-    /**
-     * 鐢ㄦ埛绫诲瀷锛坰ys_user绯荤粺鐢ㄦ埛锛�
-     */
-    private String userType;
-
-    /**
-     * 鐢ㄦ埛閭
-     */
-    private String email;
-
-    /**
-     * 鎵嬫満鍙风爜
-     */
-    private String phonenumber;
-
-    /**
-     * 鐢ㄦ埛鎬у埆锛�0鐢� 1濂� 2鏈煡锛�
-     */
-    private String sex;
-
-    /**
-     * 澶村儚鍦板潃
-     */
-    @Translation(type = TransConstant.OSS_ID_TO_URL)
-    private Long avatar;
-
-    /**
-     * 瀵嗙爜
-     */
-    @JsonIgnore
-    @JsonProperty
-    private String password;
-
-    /**
-     * 甯愬彿鐘舵�侊紙0姝e父 1鍋滅敤锛�
-     */
-    private String status;
-
-    /**
-     * 鏈�鍚庣櫥褰旾P
-     */
-    private String loginIp;
-
-    /**
-     * 鏈�鍚庣櫥褰曟椂闂�
-     */
-    private Date loginDate;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-    /**
-     * 鍒涘缓鏃堕棿
-     */
-    private Date createTime;
-
-    /**
-     * 閮ㄩ棬瀵硅薄
-     */
-    private SysDeptVo dept;
-
-    /**
-     * 瑙掕壊瀵硅薄
-     */
-    private List<SysRoleVo> roles;
-
-    /**
-     * 瑙掕壊缁�
-     */
-    private Long[] roleIds;
-
-    /**
-     * 宀椾綅缁�
-     */
-    private Long[] postIds;
-
-    /**
-     * 鏁版嵁鏉冮檺 褰撳墠瑙掕壊ID
-     */
-    private Long roleId;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/UserInfoVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/UserInfoVo.java
deleted file mode 100644
index 99b517b..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/UserInfoVo.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.ruoyi.system.domain.vo;
-
-import com.ruoyi.system.domain.vo.SysUserVo;
-import lombok.Data;
-
-import java.util.Set;
-
-/**
- * 鐧诲綍鐢ㄦ埛淇℃伅
- *
- * @author Michelle.Chung
- */
-@Data
-public class UserInfoVo {
-
-    /**
-     * 鐢ㄦ埛鍩烘湰淇℃伅
-     */
-    private SysUserVo user;
-
-    /**
-     * 鑿滃崟鏉冮檺
-     */
-    private Set<String> permissions;
-
-    /**
-     * 瑙掕壊鏉冮檺
-     */
-    private Set<String> roles;
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/listener/SysUserImportListener.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/listener/SysUserImportListener.java
deleted file mode 100644
index f442317..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/listener/SysUserImportListener.java
+++ /dev/null
@@ -1,119 +0,0 @@
-package com.ruoyi.system.listener;
-
-import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.crypto.digest.BCrypt;
-import com.alibaba.excel.context.AnalysisContext;
-import com.alibaba.excel.event.AnalysisEventListener;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.utils.SpringUtils;
-import com.ruoyi.common.core.utils.ValidatorUtils;
-import com.ruoyi.common.excel.core.ExcelListener;
-import com.ruoyi.common.excel.core.ExcelResult;
-import com.ruoyi.common.satoken.utils.LoginHelper;
-import com.ruoyi.system.domain.bo.SysUserBo;
-import com.ruoyi.system.domain.vo.SysUserImportVo;
-import com.ruoyi.system.domain.vo.SysUserVo;
-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 Long operUserId;
-
-    private int successNum = 0;
-    private int failureNum = 0;
-    private final StringBuilder successMsg = new StringBuilder();
-    private final StringBuilder failureMsg = new StringBuilder();
-
-    public SysUserImportListener(Boolean isUpdateSupport) {
-        String initPassword = SpringUtils.getBean(ISysConfigService.class).selectConfigByKey("sys.user.initPassword");
-        this.userService = SpringUtils.getBean(ISysUserService.class);
-        this.password = BCrypt.hashpw(initPassword);
-        this.isUpdateSupport = isUpdateSupport;
-        this.operUserId = LoginHelper.getUserId();
-    }
-
-    @Override
-    public void invoke(SysUserImportVo userVo, AnalysisContext context) {
-        SysUserVo sysUser = this.userService.selectUserByUserName(userVo.getUserName());
-        try {
-            // 楠岃瘉鏄惁瀛樺湪杩欎釜鐢ㄦ埛
-            if (ObjectUtil.isNull(sysUser)) {
-                SysUserBo user = BeanUtil.toBean(userVo, SysUserBo.class);
-                ValidatorUtils.validate(user);
-                user.setPassword(password);
-                user.setCreateBy(operUserId);
-                userService.insertUser(user);
-                successNum++;
-                successMsg.append("<br/>").append(successNum).append("銆佽处鍙� ").append(user.getUserName()).append(" 瀵煎叆鎴愬姛");
-            } else if (isUpdateSupport) {
-                Long userId = sysUser.getUserId();
-                SysUserBo user = BeanUtil.toBean(userVo, SysUserBo.class);
-                user.setUserId(userId);
-                ValidatorUtils.validate(user);
-                userService.checkUserAllowed(user.getUserId());
-                userService.checkUserDataScope(user.getUserId());
-                user.setUpdateBy(operUserId);
-                userService.updateUser(user);
-                successNum++;
-                successMsg.append("<br/>").append(successNum).append("銆佽处鍙� ").append(user.getUserName()).append(" 鏇存柊鎴愬姛");
-            } else {
-                failureNum++;
-                failureMsg.append("<br/>").append(failureNum).append("銆佽处鍙� ").append(sysUser.getUserName()).append(" 宸插瓨鍦�");
-            }
-        } catch (Exception e) {
-            failureNum++;
-            String msg = "<br/>" + failureNum + "銆佽处鍙� " + sysUser.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<>() {
-
-            @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-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigMapper.java
deleted file mode 100644
index a750693..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigMapper.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.ruoyi.system.mapper;
-
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.system.domain.SysConfig;
-import com.ruoyi.system.domain.vo.SysConfigVo;
-
-/**
- * 鍙傛暟閰嶇疆 鏁版嵁灞�
- *
- * @author Lion Li
- */
-public interface SysConfigMapper extends BaseMapperPlus<SysConfig, SysConfigVo> {
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java
deleted file mode 100644
index f3ef002..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package com.ruoyi.system.mapper;
-
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
-import com.baomidou.mybatisplus.core.toolkit.Constants;
-import com.ruoyi.common.mybatis.annotation.DataColumn;
-import com.ruoyi.common.mybatis.annotation.DataPermission;
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.system.domain.SysDept;
-import com.ruoyi.system.domain.vo.SysDeptVo;
-import org.apache.ibatis.annotations.Param;
-
-import java.util.List;
-
-/**
- * 閮ㄩ棬绠$悊 鏁版嵁灞�
- *
- * @author Lion Li
- */
-public interface SysDeptMapper extends BaseMapperPlus<SysDept, SysDeptVo> {
-
-    /**
-     * 鏌ヨ閮ㄩ棬绠$悊鏁版嵁
-     *
-     * @param queryWrapper 鏌ヨ鏉′欢
-     * @return 閮ㄩ棬淇℃伅闆嗗悎
-     */
-    @DataPermission({
-        @DataColumn(key = "deptName", value = "dept_id")
-    })
-    List<SysDeptVo> selectDeptList(@Param(Constants.WRAPPER) Wrapper<SysDept> queryWrapper);
-
-    @DataPermission({
-        @DataColumn(key = "deptName", value = "dept_id")
-    })
-    SysDeptVo selectDeptById(Long deptId);
-
-    /**
-     * 鏍规嵁瑙掕壊ID鏌ヨ閮ㄩ棬鏍戜俊鎭�
-     *
-     * @param roleId            瑙掕壊ID
-     * @param deptCheckStrictly 閮ㄩ棬鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�
-     * @return 閫変腑閮ㄩ棬鍒楄〃
-     */
-    List<Long> selectDeptListByRoleId(@Param("roleId") Long roleId, @Param("deptCheckStrictly") boolean deptCheckStrictly);
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java
deleted file mode 100644
index 6010a20..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.ruoyi.system.mapper;
-
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.ruoyi.common.core.constant.UserConstants;
-import com.ruoyi.system.domain.SysDictData;
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.system.domain.vo.SysDictDataVo;
-
-import java.util.List;
-
-/**
- * 瀛楀吀琛� 鏁版嵁灞�
- *
- * @author Lion Li
- */
-public interface SysDictDataMapper extends BaseMapperPlus<SysDictData, SysDictDataVo> {
-
-    default List<SysDictDataVo> selectDictDataByType(String dictType) {
-        return selectVoList(
-            new LambdaQueryWrapper<SysDictData>()
-                .eq(SysDictData::getStatus, UserConstants.DICT_NORMAL)
-                .eq(SysDictData::getDictType, dictType)
-                .orderByAsc(SysDictData::getDictSort));
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictTypeMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictTypeMapper.java
deleted file mode 100644
index 4692df3..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictTypeMapper.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.ruoyi.system.mapper;
-
-import com.ruoyi.system.domain.SysDictType;
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.system.domain.vo.SysDictTypeVo;
-
-/**
- * 瀛楀吀琛� 鏁版嵁灞�
- *
- * @author Lion Li
- */
-public interface SysDictTypeMapper extends BaseMapperPlus<SysDictType, SysDictTypeVo> {
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysLogininforMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysLogininforMapper.java
deleted file mode 100644
index da8f86c..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysLogininforMapper.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.ruoyi.system.mapper;
-
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.system.domain.SysLogininfor;
-import com.ruoyi.system.domain.vo.SysLogininforVo;
-
-/**
- * 绯荤粺璁块棶鏃ュ織鎯呭喌淇℃伅 鏁版嵁灞�
- *
- * @author Lion Li
- */
-public interface SysLogininforMapper extends BaseMapperPlus<SysLogininfor, SysLogininforVo> {
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java
deleted file mode 100644
index b77934e..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package com.ruoyi.system.mapper;
-
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Constants;
-import com.ruoyi.common.core.constant.UserConstants;
-import com.ruoyi.system.domain.SysMenu;
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.system.domain.vo.SysMenuVo;
-import org.apache.ibatis.annotations.Param;
-
-import java.util.List;
-
-/**
- * 鑿滃崟琛� 鏁版嵁灞�
- *
- * @author Lion Li
- */
-public interface SysMenuMapper extends BaseMapperPlus<SysMenu, SysMenuVo> {
-
-    /**
-     * 鏍规嵁鐢ㄦ埛鎵�鏈夋潈闄�
-     *
-     * @return 鏉冮檺鍒楄〃
-     */
-    List<String> selectMenuPerms();
-
-    /**
-     * 鏍规嵁鐢ㄦ埛鏌ヨ绯荤粺鑿滃崟鍒楄〃
-     *
-     * @param queryWrapper 鏌ヨ鏉′欢
-     * @return 鑿滃崟鍒楄〃
-     */
-    List<SysMenu> selectMenuListByUserId(@Param(Constants.WRAPPER) Wrapper<SysMenu> queryWrapper);
-
-    /**
-     * 鏍规嵁鐢ㄦ埛ID鏌ヨ鏉冮檺
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 鏉冮檺鍒楄〃
-     */
-    List<String> selectMenuPermsByUserId(Long userId);
-
-    /**
-     * 鏍规嵁瑙掕壊ID鏌ヨ鏉冮檺
-     *
-     * @param roleId 瑙掕壊ID
-     * @return 鏉冮檺鍒楄〃
-     */
-    List<String> selectMenuPermsByRoleId(Long roleId);
-
-    /**
-     * 鏍规嵁鐢ㄦ埛ID鏌ヨ鑿滃崟
-     *
-     * @return 鑿滃崟鍒楄〃
-     */
-    default List<SysMenu> selectMenuTreeAll() {
-        LambdaQueryWrapper<SysMenu> lqw = new LambdaQueryWrapper<SysMenu>()
-            .in(SysMenu::getMenuType, UserConstants.TYPE_DIR, UserConstants.TYPE_MENU)
-            .eq(SysMenu::getStatus, UserConstants.MENU_NORMAL)
-            .orderByAsc(SysMenu::getParentId)
-            .orderByAsc(SysMenu::getOrderNum);
-        return this.selectList(lqw);
-    }
-
-    /**
-     * 鏍规嵁鐢ㄦ埛ID鏌ヨ鑿滃崟
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 鑿滃崟鍒楄〃
-     */
-    List<SysMenu> selectMenuTreeByUserId(Long userId);
-
-    /**
-     * 鏍规嵁瑙掕壊ID鏌ヨ鑿滃崟鏍戜俊鎭�
-     *
-     * @param roleId            瑙掕壊ID
-     * @param menuCheckStrictly 鑿滃崟鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�
-     * @return 閫変腑鑿滃崟鍒楄〃
-     */
-    List<Long> selectMenuListByRoleId(@Param("roleId") Long roleId, @Param("menuCheckStrictly") boolean menuCheckStrictly);
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysNoticeMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysNoticeMapper.java
deleted file mode 100644
index 0c7ae46..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysNoticeMapper.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.ruoyi.system.mapper;
-
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.system.domain.SysNotice;
-import com.ruoyi.system.domain.vo.SysNoticeVo;
-
-/**
- * 閫氱煡鍏憡琛� 鏁版嵁灞�
- *
- * @author Lion Li
- */
-public interface SysNoticeMapper extends BaseMapperPlus<SysNotice, SysNoticeVo> {
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOperLogMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOperLogMapper.java
deleted file mode 100644
index edc112d..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOperLogMapper.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.ruoyi.system.mapper;
-
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.system.domain.SysOperLog;
-import com.ruoyi.system.domain.vo.SysOperLogVo;
-
-/**
- * 鎿嶄綔鏃ュ織 鏁版嵁灞�
- *
- * @author Lion Li
- */
-public interface SysOperLogMapper extends BaseMapperPlus<SysOperLog, SysOperLogVo> {
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOssConfigMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOssConfigMapper.java
deleted file mode 100644
index b4a721c..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOssConfigMapper.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.ruoyi.system.mapper;
-
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.system.domain.SysOssConfig;
-import com.ruoyi.system.domain.vo.SysOssConfigVo;
-
-/**
- * 瀵硅薄瀛樺偍閰嶇疆Mapper鎺ュ彛
- *
- * @author Lion Li
- * @author 瀛よ垷鐑熼洦
- * @date 2021-08-13
- */
-public interface SysOssConfigMapper extends BaseMapperPlus<SysOssConfig, SysOssConfigVo> {
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOssMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOssMapper.java
deleted file mode 100644
index c510e2d..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOssMapper.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.ruoyi.system.mapper;
-
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.system.domain.SysOss;
-import com.ruoyi.system.domain.vo.SysOssVo;
-
-/**
- * 鏂囦欢涓婁紶 鏁版嵁灞�
- *
- * @author Lion Li
- */
-public interface SysOssMapper extends BaseMapperPlus<SysOss, SysOssVo> {
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysPostMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysPostMapper.java
deleted file mode 100644
index e699ff2..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysPostMapper.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.ruoyi.system.mapper;
-
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.system.domain.SysPost;
-import com.ruoyi.system.domain.vo.SysPostVo;
-
-import java.util.List;
-
-/**
- * 宀椾綅淇℃伅 鏁版嵁灞�
- *
- * @author Lion Li
- */
-public interface SysPostMapper extends BaseMapperPlus<SysPost, SysPostVo> {
-
-    /**
-     * 鏍规嵁鐢ㄦ埛ID鑾峰彇宀椾綅閫夋嫨妗嗗垪琛�
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 閫変腑宀椾綅ID鍒楄〃
-     */
-    List<Long> selectPostListByUserId(Long userId);
-
-    /**
-     * 鏌ヨ鐢ㄦ埛鎵�灞炲矖浣嶇粍
-     *
-     * @param userName 鐢ㄦ埛鍚�
-     * @return 缁撴灉
-     */
-    List<SysPostVo> selectPostsByUserName(String userName);
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleDeptMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleDeptMapper.java
deleted file mode 100644
index c747b02..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleDeptMapper.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.ruoyi.system.mapper;
-
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.system.domain.SysRoleDept;
-
-/**
- * 瑙掕壊涓庨儴闂ㄥ叧鑱旇〃 鏁版嵁灞�
- *
- * @author Lion Li
- */
-public interface SysRoleDeptMapper extends BaseMapperPlus<SysRoleDept, SysRoleDept> {
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java
deleted file mode 100644
index 2f47a38..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package com.ruoyi.system.mapper;
-
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
-import com.baomidou.mybatisplus.core.toolkit.Constants;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.mybatis.annotation.DataColumn;
-import com.ruoyi.common.mybatis.annotation.DataPermission;
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.system.domain.SysRole;
-import com.ruoyi.system.domain.vo.SysRoleVo;
-import org.apache.ibatis.annotations.Param;
-
-import java.util.List;
-
-/**
- * 瑙掕壊琛� 鏁版嵁灞�
- *
- * @author Lion Li
- */
-public interface SysRoleMapper extends BaseMapperPlus<SysRole, SysRoleVo> {
-
-    @DataPermission({
-        @DataColumn(key = "deptName", value = "d.dept_id")
-    })
-    Page<SysRoleVo> selectPageRoleList(@Param("page") Page<SysRole> page, @Param(Constants.WRAPPER) Wrapper<SysRole> queryWrapper);
-
-    /**
-     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瑙掕壊鏁版嵁
-     *
-     * @param queryWrapper 鏌ヨ鏉′欢
-     * @return 瑙掕壊鏁版嵁闆嗗悎淇℃伅
-     */
-    @DataPermission({
-        @DataColumn(key = "deptName", value = "d.dept_id")
-    })
-    List<SysRoleVo> selectRoleList(@Param(Constants.WRAPPER) Wrapper<SysRole> queryWrapper);
-
-    @DataPermission({
-        @DataColumn(key = "deptName", value = "d.dept_id")
-    })
-    SysRoleVo selectRoleById(Long roleId);
-
-    /**
-     * 鏍规嵁鐢ㄦ埛ID鏌ヨ瑙掕壊
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 瑙掕壊鍒楄〃
-     */
-    List<SysRoleVo> selectRolePermissionByUserId(Long userId);
-
-
-    /**
-     * 鏍规嵁鐢ㄦ埛ID鑾峰彇瑙掕壊閫夋嫨妗嗗垪琛�
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 閫変腑瑙掕壊ID鍒楄〃
-     */
-    List<Long> selectRoleListByUserId(Long userId);
-
-    /**
-     * 鏍规嵁鐢ㄦ埛ID鏌ヨ瑙掕壊
-     *
-     * @param userName 鐢ㄦ埛鍚�
-     * @return 瑙掕壊鍒楄〃
-     */
-    List<SysRoleVo> selectRolesByUserName(String userName);
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java
deleted file mode 100644
index b300063..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.ruoyi.system.mapper;
-
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.system.domain.SysRoleMenu;
-
-/**
- * 瑙掕壊涓庤彍鍗曞叧鑱旇〃 鏁版嵁灞�
- *
- * @author Lion Li
- */
-public interface SysRoleMenuMapper extends BaseMapperPlus<SysRoleMenu, SysRoleMenu> {
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTenantMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTenantMapper.java
deleted file mode 100644
index d110fda..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTenantMapper.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.ruoyi.system.mapper;
-
-import com.ruoyi.system.domain.SysTenant;
-import com.ruoyi.system.domain.vo.SysTenantVo;
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-
-/**
- * 绉熸埛Mapper鎺ュ彛
- *
- * @author Michelle.Chung
- */
-public interface SysTenantMapper extends BaseMapperPlus<SysTenant, SysTenantVo> {
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTenantPackageMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTenantPackageMapper.java
deleted file mode 100644
index 5215f26..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTenantPackageMapper.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.ruoyi.system.mapper;
-
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.system.domain.SysTenantPackage;
-import com.ruoyi.system.domain.vo.SysTenantPackageVo;
-
-/**
- * 绉熸埛濂楅Mapper鎺ュ彛
- *
- * @author Michelle.Chung
- */
-public interface SysTenantPackageMapper extends BaseMapperPlus<SysTenantPackage, SysTenantPackageVo> {
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java
deleted file mode 100644
index 2aacf48..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java
+++ /dev/null
@@ -1,145 +0,0 @@
-package com.ruoyi.system.mapper;
-
-import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
-import com.baomidou.mybatisplus.core.toolkit.Constants;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.mybatis.annotation.DataColumn;
-import com.ruoyi.common.mybatis.annotation.DataPermission;
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.system.domain.SysUser;
-import com.ruoyi.system.domain.vo.SysUserVo;
-import org.apache.ibatis.annotations.Param;
-
-import java.util.List;
-
-/**
- * 鐢ㄦ埛琛� 鏁版嵁灞�
- *
- * @author Lion Li
- */
-public interface SysUserMapper extends BaseMapperPlus<SysUser, SysUserVo> {
-
-    @DataPermission({
-        @DataColumn(key = "deptName", value = "d.dept_id"),
-        @DataColumn(key = "userName", value = "u.user_id")
-    })
-    Page<SysUserVo> selectPageUserList(@Param("page") Page<SysUser> page, @Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);
-
-    /**
-     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ鐢ㄦ埛鍒楄〃
-     *
-     * @param queryWrapper 鏌ヨ鏉′欢
-     * @return 鐢ㄦ埛淇℃伅闆嗗悎淇℃伅
-     */
-    @DataPermission({
-        @DataColumn(key = "deptName", value = "d.dept_id"),
-        @DataColumn(key = "userName", value = "u.user_id")
-    })
-    List<SysUserVo> selectUserList(@Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);
-
-    /**
-     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ宸查厤鐢ㄦ埛瑙掕壊鍒楄〃
-     *
-     * @param queryWrapper 鏌ヨ鏉′欢
-     * @return 鐢ㄦ埛淇℃伅闆嗗悎淇℃伅
-     */
-    @DataPermission({
-        @DataColumn(key = "deptName", value = "d.dept_id"),
-        @DataColumn(key = "userName", value = "u.user_id")
-    })
-    Page<SysUserVo> selectAllocatedList(@Param("page") Page<SysUser> page, @Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);
-
-    /**
-     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ鏈垎閰嶇敤鎴疯鑹插垪琛�
-     *
-     * @param queryWrapper 鏌ヨ鏉′欢
-     * @return 鐢ㄦ埛淇℃伅闆嗗悎淇℃伅
-     */
-    @DataPermission({
-        @DataColumn(key = "deptName", value = "d.dept_id"),
-        @DataColumn(key = "userName", value = "u.user_id")
-    })
-    Page<SysUserVo> selectUnallocatedList(@Param("page") Page<SysUser> page, @Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);
-
-    /**
-     * 閫氳繃鐢ㄦ埛鍚嶆煡璇㈢敤鎴�
-     *
-     * @param userName 鐢ㄦ埛鍚�
-     * @return 鐢ㄦ埛瀵硅薄淇℃伅
-     */
-    SysUserVo selectUserByUserName(String userName);
-
-    /**
-     * 閫氳繃鎵嬫満鍙锋煡璇㈢敤鎴�
-     *
-     * @param phonenumber 鎵嬫満鍙�
-     * @return 鐢ㄦ埛瀵硅薄淇℃伅
-     */
-    SysUserVo selectUserByPhonenumber(String phonenumber);
-
-    /**
-     * 閫氳繃閭鏌ヨ鐢ㄦ埛
-     *
-     * @param email 閭
-     * @return 鐢ㄦ埛瀵硅薄淇℃伅
-     */
-    SysUserVo selectUserByEmail(String email);
-
-    /**
-     * 閫氳繃鐢ㄦ埛鍚嶆煡璇㈢敤鎴�(涓嶈蛋绉熸埛鎻掍欢)
-     *
-     * @param userName 鐢ㄦ埛鍚�
-     * @param tenantId 绉熸埛id
-     * @return 鐢ㄦ埛瀵硅薄淇℃伅
-     */
-    @InterceptorIgnore(tenantLine = "true")
-    SysUserVo selectTenantUserByUserName(String userName, String tenantId);
-
-    /**
-     * 閫氳繃鎵嬫満鍙锋煡璇㈢敤鎴�(涓嶈蛋绉熸埛鎻掍欢)
-     *
-     * @param phonenumber 鎵嬫満鍙�
-     * @param tenantId    绉熸埛id
-     * @return 鐢ㄦ埛瀵硅薄淇℃伅
-     */
-    @InterceptorIgnore(tenantLine = "true")
-    SysUserVo selectTenantUserByPhonenumber(String phonenumber, String tenantId);
-
-    /**
-     * 閫氳繃閭鏌ヨ鐢ㄦ埛(涓嶈蛋绉熸埛鎻掍欢)
-     *
-     * @param email    閭
-     * @param tenantId 绉熸埛id
-     * @return 鐢ㄦ埛瀵硅薄淇℃伅
-     */
-    @InterceptorIgnore(tenantLine = "true")
-    SysUserVo selectTenantUserByEmail(String email, String tenantId);
-
-    /**
-     * 閫氳繃鐢ㄦ埛ID鏌ヨ鐢ㄦ埛
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 鐢ㄦ埛瀵硅薄淇℃伅
-     */
-    @DataPermission({
-        @DataColumn(key = "deptName", value = "d.dept_id"),
-        @DataColumn(key = "userName", value = "u.user_id")
-    })
-    SysUserVo selectUserById(Long userId);
-
-    @Override
-    @DataPermission({
-        @DataColumn(key = "deptName", value = "dept_id"),
-        @DataColumn(key = "userName", value = "user_id")
-    })
-    int update(@Param(Constants.ENTITY) SysUser user, @Param(Constants.WRAPPER) Wrapper<SysUser> updateWrapper);
-
-    @Override
-    @DataPermission({
-        @DataColumn(key = "deptName", value = "dept_id"),
-        @DataColumn(key = "userName", value = "user_id")
-    })
-    int updateById(@Param(Constants.ENTITY) SysUser user);
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserPostMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserPostMapper.java
deleted file mode 100644
index 9e5eb1c..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserPostMapper.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.ruoyi.system.mapper;
-
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.system.domain.SysUserPost;
-
-/**
- * 鐢ㄦ埛涓庡矖浣嶅叧鑱旇〃 鏁版嵁灞�
- *
- * @author Lion Li
- */
-public interface SysUserPostMapper extends BaseMapperPlus<SysUserPost, SysUserPost> {
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java
deleted file mode 100644
index 5999de1..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.ruoyi.system.mapper;
-
-import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import com.ruoyi.system.domain.SysUserRole;
-
-import java.util.List;
-
-/**
- * 鐢ㄦ埛涓庤鑹插叧鑱旇〃 鏁版嵁灞�
- *
- * @author Lion Li
- */
-public interface SysUserRoleMapper extends BaseMapperPlus<SysUserRole, SysUserRole> {
-
-    List<Long> selectUserIdsByRoleId(Long roleId);
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/runner/SystemApplicationRunner.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/runner/SystemApplicationRunner.java
deleted file mode 100644
index e44cf87..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/runner/SystemApplicationRunner.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.ruoyi.system.runner;
-
-import com.ruoyi.system.service.ISysOssConfigService;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.boot.ApplicationArguments;
-import org.springframework.boot.ApplicationRunner;
-import org.springframework.stereotype.Component;
-
-/**
- * 鍒濆鍖� system 妯″潡瀵瑰簲涓氬姟鏁版嵁
- *
- * @author Lion Li
- */
-@Slf4j
-@RequiredArgsConstructor
-@Component
-public class SystemApplicationRunner implements ApplicationRunner {
-
-    private final ISysOssConfigService ossConfigService;
-
-    @Override
-    public void run(ApplicationArguments args) throws Exception {
-        ossConfigService.init();
-        log.info("鍒濆鍖朞SS閰嶇疆鎴愬姛");
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigService.java
deleted file mode 100644
index 4fa1bf3..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigService.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package com.ruoyi.system.service;
-
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.system.domain.bo.SysConfigBo;
-import com.ruoyi.system.domain.vo.SysConfigVo;
-
-import java.util.List;
-
-/**
- * 鍙傛暟閰嶇疆 鏈嶅姟灞�
- *
- * @author Lion Li
- */
-public interface ISysConfigService {
-
-
-    TableDataInfo<SysConfigVo> selectPageConfigList(SysConfigBo config, PageQuery pageQuery);
-
-    /**
-     * 鏌ヨ鍙傛暟閰嶇疆淇℃伅
-     *
-     * @param configId 鍙傛暟閰嶇疆ID
-     * @return 鍙傛暟閰嶇疆淇℃伅
-     */
-    SysConfigVo selectConfigById(Long configId);
-
-    /**
-     * 鏍规嵁閿悕鏌ヨ鍙傛暟閰嶇疆淇℃伅
-     *
-     * @param configKey 鍙傛暟閿悕
-     * @return 鍙傛暟閿��
-     */
-    String selectConfigByKey(String configKey);
-
-    /**
-     * 鑾峰彇娉ㄥ唽寮�鍏�
-     * @param tenantId 绉熸埛id
-     * @return true寮�鍚紝false鍏抽棴
-     */
-    boolean selectRegisterEnabled(String tenantId);
-
-    /**
-     * 鏌ヨ鍙傛暟閰嶇疆鍒楄〃
-     *
-     * @param config 鍙傛暟閰嶇疆淇℃伅
-     * @return 鍙傛暟閰嶇疆闆嗗悎
-     */
-    List<SysConfigVo> selectConfigList(SysConfigBo config);
-
-    /**
-     * 鏂板鍙傛暟閰嶇疆
-     *
-     * @param bo 鍙傛暟閰嶇疆淇℃伅
-     * @return 缁撴灉
-     */
-    String insertConfig(SysConfigBo bo);
-
-    /**
-     * 淇敼鍙傛暟閰嶇疆
-     *
-     * @param bo 鍙傛暟閰嶇疆淇℃伅
-     * @return 缁撴灉
-     */
-    String updateConfig(SysConfigBo bo);
-
-    /**
-     * 鎵归噺鍒犻櫎鍙傛暟淇℃伅
-     *
-     * @param configIds 闇�瑕佸垹闄ょ殑鍙傛暟ID
-     */
-    void deleteConfigByIds(Long[] configIds);
-
-    /**
-     * 閲嶇疆鍙傛暟缂撳瓨鏁版嵁
-     */
-    void resetConfigCache();
-
-    /**
-     * 鏍¢獙鍙傛暟閿悕鏄惁鍞竴
-     *
-     * @param config 鍙傛暟淇℃伅
-     * @return 缁撴灉
-     */
-    boolean checkConfigKeyUnique(SysConfigBo config);
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDataScopeService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDataScopeService.java
deleted file mode 100644
index 4ad4e45..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDataScopeService.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.ruoyi.system.service;
-
-/**
- * 閫氱敤 鏁版嵁鏉冮檺 鏈嶅姟
- *
- * @author Lion Li
- */
-public interface ISysDataScopeService {
-
-    /**
-     * 鑾峰彇瑙掕壊鑷畾涔夋潈闄�
-     *
-     * @param roleId 瑙掕壊id
-     * @return 閮ㄩ棬id缁�
-     */
-    String getRoleCustom(Long roleId);
-
-    /**
-     * 鑾峰彇閮ㄩ棬鍙婁互涓嬫潈闄�
-     *
-     * @param deptId 閮ㄩ棬id
-     * @return 閮ㄩ棬id缁�
-     */
-    String getDeptAndChild(Long deptId);
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java
deleted file mode 100644
index e82e443..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package com.ruoyi.system.service;
-
-import cn.hutool.core.lang.tree.Tree;
-import com.ruoyi.system.domain.SysDept;
-import com.ruoyi.system.domain.bo.SysDeptBo;
-import com.ruoyi.system.domain.vo.SysDeptVo;
-
-import java.util.List;
-
-/**
- * 閮ㄩ棬绠$悊 鏈嶅姟灞�
- *
- * @author Lion Li
- */
-public interface ISysDeptService {
-    /**
-     * 鏌ヨ閮ㄩ棬绠$悊鏁版嵁
-     *
-     * @param dept 閮ㄩ棬淇℃伅
-     * @return 閮ㄩ棬淇℃伅闆嗗悎
-     */
-    List<SysDeptVo> selectDeptList(SysDeptBo dept);
-
-    /**
-     * 鏌ヨ閮ㄩ棬鏍戠粨鏋勪俊鎭�
-     *
-     * @param dept 閮ㄩ棬淇℃伅
-     * @return 閮ㄩ棬鏍戜俊鎭泦鍚�
-     */
-    List<Tree<Long>> selectDeptTreeList(SysDeptBo dept);
-
-    /**
-     * 鏋勫缓鍓嶇鎵�闇�瑕佷笅鎷夋爲缁撴瀯
-     *
-     * @param depts 閮ㄩ棬鍒楄〃
-     * @return 涓嬫媺鏍戠粨鏋勫垪琛�
-     */
-    List<Tree<Long>> buildDeptTreeSelect(List<SysDept> depts);
-
-    /**
-     * 鏍规嵁瑙掕壊ID鏌ヨ閮ㄩ棬鏍戜俊鎭�
-     *
-     * @param roleId 瑙掕壊ID
-     * @return 閫変腑閮ㄩ棬鍒楄〃
-     */
-    List<Long> selectDeptListByRoleId(Long roleId);
-
-    /**
-     * 鏍规嵁閮ㄩ棬ID鏌ヨ淇℃伅
-     *
-     * @param deptId 閮ㄩ棬ID
-     * @return 閮ㄩ棬淇℃伅
-     */
-    SysDeptVo selectDeptById(Long deptId);
-
-    /**
-     * 鏍规嵁ID鏌ヨ鎵�鏈夊瓙閮ㄩ棬鏁帮紙姝e父鐘舵�侊級
-     *
-     * @param deptId 閮ㄩ棬ID
-     * @return 瀛愰儴闂ㄦ暟
-     */
-    long selectNormalChildrenDeptById(Long deptId);
-
-    /**
-     * 鏄惁瀛樺湪閮ㄩ棬瀛愯妭鐐�
-     *
-     * @param deptId 閮ㄩ棬ID
-     * @return 缁撴灉
-     */
-    boolean hasChildByDeptId(Long deptId);
-
-    /**
-     * 鏌ヨ閮ㄩ棬鏄惁瀛樺湪鐢ㄦ埛
-     *
-     * @param deptId 閮ㄩ棬ID
-     * @return 缁撴灉 true 瀛樺湪 false 涓嶅瓨鍦�
-     */
-    boolean checkDeptExistUser(Long deptId);
-
-    /**
-     * 鏍¢獙閮ㄩ棬鍚嶇О鏄惁鍞竴
-     *
-     * @param dept 閮ㄩ棬淇℃伅
-     * @return 缁撴灉
-     */
-    boolean checkDeptNameUnique(SysDeptBo dept);
-
-    /**
-     * 鏍¢獙閮ㄩ棬鏄惁鏈夋暟鎹潈闄�
-     *
-     * @param deptId 閮ㄩ棬id
-     */
-    void checkDeptDataScope(Long deptId);
-
-    /**
-     * 鏂板淇濆瓨閮ㄩ棬淇℃伅
-     *
-     * @param bo 閮ㄩ棬淇℃伅
-     * @return 缁撴灉
-     */
-    int insertDept(SysDeptBo bo);
-
-    /**
-     * 淇敼淇濆瓨閮ㄩ棬淇℃伅
-     *
-     * @param bo 閮ㄩ棬淇℃伅
-     * @return 缁撴灉
-     */
-    int updateDept(SysDeptBo bo);
-
-    /**
-     * 鍒犻櫎閮ㄩ棬绠$悊淇℃伅
-     *
-     * @param deptId 閮ㄩ棬ID
-     * @return 缁撴灉
-     */
-    int deleteDeptById(Long deptId);
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java
deleted file mode 100644
index f8c8721..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.ruoyi.system.service;
-
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.system.domain.bo.SysDictDataBo;
-import com.ruoyi.system.domain.vo.SysDictDataVo;
-
-import java.util.List;
-
-/**
- * 瀛楀吀 涓氬姟灞�
- *
- * @author Lion Li
- */
-public interface ISysDictDataService {
-
-
-    TableDataInfo<SysDictDataVo> selectPageDictDataList(SysDictDataBo dictData, PageQuery pageQuery);
-
-    /**
-     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瀛楀吀鏁版嵁
-     *
-     * @param dictData 瀛楀吀鏁版嵁淇℃伅
-     * @return 瀛楀吀鏁版嵁闆嗗悎淇℃伅
-     */
-    List<SysDictDataVo> selectDictDataList(SysDictDataBo dictData);
-
-    /**
-     * 鏍规嵁瀛楀吀绫诲瀷鍜屽瓧鍏搁敭鍊兼煡璇㈠瓧鍏告暟鎹俊鎭�
-     *
-     * @param dictType  瀛楀吀绫诲瀷
-     * @param dictValue 瀛楀吀閿��
-     * @return 瀛楀吀鏍囩
-     */
-    String selectDictLabel(String dictType, String dictValue);
-
-    /**
-     * 鏍规嵁瀛楀吀鏁版嵁ID鏌ヨ淇℃伅
-     *
-     * @param dictCode 瀛楀吀鏁版嵁ID
-     * @return 瀛楀吀鏁版嵁
-     */
-    SysDictDataVo selectDictDataById(Long dictCode);
-
-    /**
-     * 鎵归噺鍒犻櫎瀛楀吀鏁版嵁淇℃伅
-     *
-     * @param dictCodes 闇�瑕佸垹闄ょ殑瀛楀吀鏁版嵁ID
-     */
-    void deleteDictDataByIds(Long[] dictCodes);
-
-    /**
-     * 鏂板淇濆瓨瀛楀吀鏁版嵁淇℃伅
-     *
-     * @param bo 瀛楀吀鏁版嵁淇℃伅
-     * @return 缁撴灉
-     */
-    List<SysDictDataVo> insertDictData(SysDictDataBo bo);
-
-    /**
-     * 淇敼淇濆瓨瀛楀吀鏁版嵁淇℃伅
-     *
-     * @param bo 瀛楀吀鏁版嵁淇℃伅
-     * @return 缁撴灉
-     */
-    List<SysDictDataVo> updateDictData(SysDictDataBo bo);
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java
deleted file mode 100644
index ad8d30d..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package com.ruoyi.system.service;
-
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.system.domain.bo.SysDictTypeBo;
-import com.ruoyi.system.domain.vo.SysDictDataVo;
-import com.ruoyi.system.domain.vo.SysDictTypeVo;
-
-import java.util.List;
-
-/**
- * 瀛楀吀 涓氬姟灞�
- *
- * @author Lion Li
- */
-public interface ISysDictTypeService {
-
-
-    TableDataInfo<SysDictTypeVo> selectPageDictTypeList(SysDictTypeBo dictType, PageQuery pageQuery);
-
-    /**
-     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瀛楀吀绫诲瀷
-     *
-     * @param dictType 瀛楀吀绫诲瀷淇℃伅
-     * @return 瀛楀吀绫诲瀷闆嗗悎淇℃伅
-     */
-    List<SysDictTypeVo> selectDictTypeList(SysDictTypeBo dictType);
-
-    /**
-     * 鏍规嵁鎵�鏈夊瓧鍏哥被鍨�
-     *
-     * @return 瀛楀吀绫诲瀷闆嗗悎淇℃伅
-     */
-    List<SysDictTypeVo> selectDictTypeAll();
-
-    /**
-     * 鏍规嵁瀛楀吀绫诲瀷鏌ヨ瀛楀吀鏁版嵁
-     *
-     * @param dictType 瀛楀吀绫诲瀷
-     * @return 瀛楀吀鏁版嵁闆嗗悎淇℃伅
-     */
-    List<SysDictDataVo> selectDictDataByType(String dictType);
-
-    /**
-     * 鏍规嵁瀛楀吀绫诲瀷ID鏌ヨ淇℃伅
-     *
-     * @param dictId 瀛楀吀绫诲瀷ID
-     * @return 瀛楀吀绫诲瀷
-     */
-    SysDictTypeVo selectDictTypeById(Long dictId);
-
-    /**
-     * 鏍规嵁瀛楀吀绫诲瀷鏌ヨ淇℃伅
-     *
-     * @param dictType 瀛楀吀绫诲瀷
-     * @return 瀛楀吀绫诲瀷
-     */
-    SysDictTypeVo selectDictTypeByType(String dictType);
-
-    /**
-     * 鎵归噺鍒犻櫎瀛楀吀淇℃伅
-     *
-     * @param dictIds 闇�瑕佸垹闄ょ殑瀛楀吀ID
-     */
-    void deleteDictTypeByIds(Long[] dictIds);
-
-    /**
-     * 閲嶇疆瀛楀吀缂撳瓨鏁版嵁
-     */
-    void resetDictCache();
-
-    /**
-     * 鏂板淇濆瓨瀛楀吀绫诲瀷淇℃伅
-     *
-     * @param bo 瀛楀吀绫诲瀷淇℃伅
-     * @return 缁撴灉
-     */
-    List<SysDictTypeVo> insertDictType(SysDictTypeBo bo);
-
-    /**
-     * 淇敼淇濆瓨瀛楀吀绫诲瀷淇℃伅
-     *
-     * @param bo 瀛楀吀绫诲瀷淇℃伅
-     * @return 缁撴灉
-     */
-    List<SysDictDataVo> updateDictType(SysDictTypeBo bo);
-
-    /**
-     * 鏍¢獙瀛楀吀绫诲瀷绉版槸鍚﹀敮涓�
-     *
-     * @param dictType 瀛楀吀绫诲瀷
-     * @return 缁撴灉
-     */
-    boolean checkDictTypeUnique(SysDictTypeBo dictType);
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysLogininforService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysLogininforService.java
deleted file mode 100644
index 4c5efc1..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysLogininforService.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.ruoyi.system.service;
-
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.system.domain.bo.SysLogininforBo;
-import com.ruoyi.system.domain.vo.SysLogininforVo;
-
-import java.util.List;
-
-/**
- * 绯荤粺璁块棶鏃ュ織鎯呭喌淇℃伅 鏈嶅姟灞�
- *
- * @author Lion Li
- */
-public interface ISysLogininforService {
-
-
-    TableDataInfo<SysLogininforVo> selectPageLogininforList(SysLogininforBo logininfor, PageQuery pageQuery);
-
-    /**
-     * 鏂板绯荤粺鐧诲綍鏃ュ織
-     *
-     * @param bo 璁块棶鏃ュ織瀵硅薄
-     */
-    void insertLogininfor(SysLogininforBo bo);
-
-    /**
-     * 鏌ヨ绯荤粺鐧诲綍鏃ュ織闆嗗悎
-     *
-     * @param logininfor 璁块棶鏃ュ織瀵硅薄
-     * @return 鐧诲綍璁板綍闆嗗悎
-     */
-    List<SysLogininforVo> selectLogininforList(SysLogininforBo logininfor);
-
-    /**
-     * 鎵归噺鍒犻櫎绯荤粺鐧诲綍鏃ュ織
-     *
-     * @param infoIds 闇�瑕佸垹闄ょ殑鐧诲綍鏃ュ織ID
-     * @return 缁撴灉
-     */
-    int deleteLogininforByIds(Long[] infoIds);
-
-    /**
-     * 娓呯┖绯荤粺鐧诲綍鏃ュ織
-     */
-    void cleanLogininfor();
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java
deleted file mode 100644
index cfe94ba..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java
+++ /dev/null
@@ -1,147 +0,0 @@
-package com.ruoyi.system.service;
-
-import cn.hutool.core.lang.tree.Tree;
-import com.ruoyi.system.domain.SysMenu;
-import com.ruoyi.system.domain.bo.SysMenuBo;
-import com.ruoyi.system.domain.vo.RouterVo;
-import com.ruoyi.system.domain.vo.SysMenuVo;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * 鑿滃崟 涓氬姟灞�
- *
- * @author Lion Li
- */
-public interface ISysMenuService {
-
-    /**
-     * 鏍规嵁鐢ㄦ埛鏌ヨ绯荤粺鑿滃崟鍒楄〃
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 鑿滃崟鍒楄〃
-     */
-    List<SysMenuVo> selectMenuList(Long userId);
-
-    /**
-     * 鏍规嵁鐢ㄦ埛鏌ヨ绯荤粺鑿滃崟鍒楄〃
-     *
-     * @param menu   鑿滃崟淇℃伅
-     * @param userId 鐢ㄦ埛ID
-     * @return 鑿滃崟鍒楄〃
-     */
-    List<SysMenuVo> selectMenuList(SysMenuBo menu, Long userId);
-
-    /**
-     * 鏍规嵁鐢ㄦ埛ID鏌ヨ鏉冮檺
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 鏉冮檺鍒楄〃
-     */
-    Set<String> selectMenuPermsByUserId(Long userId);
-
-    /**
-     * 鏍规嵁瑙掕壊ID鏌ヨ鏉冮檺
-     *
-     * @param roleId 瑙掕壊ID
-     * @return 鏉冮檺鍒楄〃
-     */
-    Set<String> selectMenuPermsByRoleId(Long roleId);
-
-    /**
-     * 鏍规嵁鐢ㄦ埛ID鏌ヨ鑿滃崟鏍戜俊鎭�
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 鑿滃崟鍒楄〃
-     */
-    List<SysMenu> selectMenuTreeByUserId(Long userId);
-
-    /**
-     * 鏍规嵁瑙掕壊ID鏌ヨ鑿滃崟鏍戜俊鎭�
-     *
-     * @param roleId 瑙掕壊ID
-     * @return 閫変腑鑿滃崟鍒楄〃
-     */
-    List<Long> selectMenuListByRoleId(Long roleId);
-
-    /**
-     * 鏍规嵁绉熸埛濂楅ID鏌ヨ鑿滃崟鏍戜俊鎭�
-     *
-     * @param packageId 绉熸埛濂楅ID
-     * @return 閫変腑鑿滃崟鍒楄〃
-     */
-    List<Long> selectMenuListByPackageId(Long packageId);
-
-    /**
-     * 鏋勫缓鍓嶇璺敱鎵�闇�瑕佺殑鑿滃崟
-     *
-     * @param menus 鑿滃崟鍒楄〃
-     * @return 璺敱鍒楄〃
-     */
-    List<RouterVo> buildMenus(List<SysMenu> menus);
-
-    /**
-     * 鏋勫缓鍓嶇鎵�闇�瑕佷笅鎷夋爲缁撴瀯
-     *
-     * @param menus 鑿滃崟鍒楄〃
-     * @return 涓嬫媺鏍戠粨鏋勫垪琛�
-     */
-    List<Tree<Long>> buildMenuTreeSelect(List<SysMenuVo> menus);
-
-    /**
-     * 鏍规嵁鑿滃崟ID鏌ヨ淇℃伅
-     *
-     * @param menuId 鑿滃崟ID
-     * @return 鑿滃崟淇℃伅
-     */
-    SysMenuVo selectMenuById(Long menuId);
-
-    /**
-     * 鏄惁瀛樺湪鑿滃崟瀛愯妭鐐�
-     *
-     * @param menuId 鑿滃崟ID
-     * @return 缁撴灉 true 瀛樺湪 false 涓嶅瓨鍦�
-     */
-    boolean hasChildByMenuId(Long menuId);
-
-    /**
-     * 鏌ヨ鑿滃崟鏄惁瀛樺湪瑙掕壊
-     *
-     * @param menuId 鑿滃崟ID
-     * @return 缁撴灉 true 瀛樺湪 false 涓嶅瓨鍦�
-     */
-    boolean checkMenuExistRole(Long menuId);
-
-    /**
-     * 鏂板淇濆瓨鑿滃崟淇℃伅
-     *
-     * @param bo 鑿滃崟淇℃伅
-     * @return 缁撴灉
-     */
-    int insertMenu(SysMenuBo bo);
-
-    /**
-     * 淇敼淇濆瓨鑿滃崟淇℃伅
-     *
-     * @param bo 鑿滃崟淇℃伅
-     * @return 缁撴灉
-     */
-    int updateMenu(SysMenuBo bo);
-
-    /**
-     * 鍒犻櫎鑿滃崟绠$悊淇℃伅
-     *
-     * @param menuId 鑿滃崟ID
-     * @return 缁撴灉
-     */
-    int deleteMenuById(Long menuId);
-
-    /**
-     * 鏍¢獙鑿滃崟鍚嶇О鏄惁鍞竴
-     *
-     * @param menu 鑿滃崟淇℃伅
-     * @return 缁撴灉
-     */
-    boolean checkMenuNameUnique(SysMenuBo menu);
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeService.java
deleted file mode 100644
index 02f9b80..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeService.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.ruoyi.system.service;
-
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.system.domain.bo.SysNoticeBo;
-import com.ruoyi.system.domain.vo.SysNoticeVo;
-
-import java.util.List;
-
-/**
- * 鍏憡 鏈嶅姟灞�
- *
- * @author Lion Li
- */
-public interface ISysNoticeService {
-
-
-    TableDataInfo<SysNoticeVo> selectPageNoticeList(SysNoticeBo notice, PageQuery pageQuery);
-
-    /**
-     * 鏌ヨ鍏憡淇℃伅
-     *
-     * @param noticeId 鍏憡ID
-     * @return 鍏憡淇℃伅
-     */
-    SysNoticeVo selectNoticeById(Long noticeId);
-
-    /**
-     * 鏌ヨ鍏憡鍒楄〃
-     *
-     * @param notice 鍏憡淇℃伅
-     * @return 鍏憡闆嗗悎
-     */
-    List<SysNoticeVo> selectNoticeList(SysNoticeBo notice);
-
-    /**
-     * 鏂板鍏憡
-     *
-     * @param bo 鍏憡淇℃伅
-     * @return 缁撴灉
-     */
-    int insertNotice(SysNoticeBo bo);
-
-    /**
-     * 淇敼鍏憡
-     *
-     * @param bo 鍏憡淇℃伅
-     * @return 缁撴灉
-     */
-    int updateNotice(SysNoticeBo bo);
-
-    /**
-     * 鍒犻櫎鍏憡淇℃伅
-     *
-     * @param noticeId 鍏憡ID
-     * @return 缁撴灉
-     */
-    int deleteNoticeById(Long noticeId);
-
-    /**
-     * 鎵归噺鍒犻櫎鍏憡淇℃伅
-     *
-     * @param noticeIds 闇�瑕佸垹闄ょ殑鍏憡ID
-     * @return 缁撴灉
-     */
-    int deleteNoticeByIds(Long[] noticeIds);
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOperLogService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOperLogService.java
deleted file mode 100644
index edce3a6..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOperLogService.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.ruoyi.system.service;
-
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.system.domain.bo.SysOperLogBo;
-import com.ruoyi.system.domain.vo.SysOperLogVo;
-
-import java.util.List;
-
-/**
- * 鎿嶄綔鏃ュ織 鏈嶅姟灞�
- *
- * @author Lion Li
- */
-public interface ISysOperLogService {
-
-    TableDataInfo<SysOperLogVo> selectPageOperLogList(SysOperLogBo operLog, PageQuery pageQuery);
-
-    /**
-     * 鏂板鎿嶄綔鏃ュ織
-     *
-     * @param bo 鎿嶄綔鏃ュ織瀵硅薄
-     */
-    void insertOperlog(SysOperLogBo bo);
-
-    /**
-     * 鏌ヨ绯荤粺鎿嶄綔鏃ュ織闆嗗悎
-     *
-     * @param operLog 鎿嶄綔鏃ュ織瀵硅薄
-     * @return 鎿嶄綔鏃ュ織闆嗗悎
-     */
-    List<SysOperLogVo> selectOperLogList(SysOperLogBo operLog);
-
-    /**
-     * 鎵归噺鍒犻櫎绯荤粺鎿嶄綔鏃ュ織
-     *
-     * @param operIds 闇�瑕佸垹闄ょ殑鎿嶄綔鏃ュ織ID
-     * @return 缁撴灉
-     */
-    int deleteOperLogByIds(Long[] operIds);
-
-    /**
-     * 鏌ヨ鎿嶄綔鏃ュ織璇︾粏
-     *
-     * @param operId 鎿嶄綔ID
-     * @return 鎿嶄綔鏃ュ織瀵硅薄
-     */
-    SysOperLogVo selectOperLogById(Long operId);
-
-    /**
-     * 娓呯┖鎿嶄綔鏃ュ織
-     */
-    void cleanOperLog();
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssConfigService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssConfigService.java
deleted file mode 100644
index f38af83..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssConfigService.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.ruoyi.system.service;
-
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.system.domain.bo.SysOssConfigBo;
-import com.ruoyi.system.domain.vo.SysOssConfigVo;
-
-import java.util.Collection;
-
-/**
- * 瀵硅薄瀛樺偍閰嶇疆Service鎺ュ彛
- *
- * @author Lion Li
- * @author 瀛よ垷鐑熼洦
- * @date 2021-08-13
- */
-public interface ISysOssConfigService {
-
-    /**
-     * 鍒濆鍖朞SS閰嶇疆
-     */
-    void init();
-
-    /**
-     * 鏌ヨ鍗曚釜
-     */
-    SysOssConfigVo queryById(Long ossConfigId);
-
-    /**
-     * 鏌ヨ鍒楄〃
-     */
-    TableDataInfo<SysOssConfigVo> queryPageList(SysOssConfigBo bo, PageQuery pageQuery);
-
-
-    /**
-     * 鏍规嵁鏂板涓氬姟瀵硅薄鎻掑叆瀵硅薄瀛樺偍閰嶇疆
-     *
-     * @param bo 瀵硅薄瀛樺偍閰嶇疆鏂板涓氬姟瀵硅薄
-     * @return
-     */
-    Boolean insertByBo(SysOssConfigBo bo);
-
-    /**
-     * 鏍规嵁缂栬緫涓氬姟瀵硅薄淇敼瀵硅薄瀛樺偍閰嶇疆
-     *
-     * @param bo 瀵硅薄瀛樺偍閰嶇疆缂栬緫涓氬姟瀵硅薄
-     * @return
-     */
-    Boolean updateByBo(SysOssConfigBo bo);
-
-    /**
-     * 鏍¢獙骞跺垹闄ゆ暟鎹�
-     *
-     * @param ids     涓婚敭闆嗗悎
-     * @param isValid 鏄惁鏍¢獙,true-鍒犻櫎鍓嶆牎楠�,false-涓嶆牎楠�
-     * @return
-     */
-    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
-
-    /**
-     * 鍚敤鍋滅敤鐘舵��
-     */
-    int updateOssConfigStatus(SysOssConfigBo bo);
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssService.java
deleted file mode 100644
index 7d518af..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssService.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.ruoyi.system.service;
-
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.system.domain.SysOss;
-import com.ruoyi.system.domain.bo.SysOssBo;
-import com.ruoyi.system.domain.vo.SysOssVo;
-import jakarta.servlet.http.HttpServletResponse;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * 鏂囦欢涓婁紶 鏈嶅姟灞�
- *
- * @author Lion Li
- */
-public interface ISysOssService {
-
-    TableDataInfo<SysOssVo> queryPageList(SysOssBo sysOss, PageQuery pageQuery);
-
-    List<SysOssVo> listByIds(Collection<Long> ossIds);
-
-    SysOssVo getById(Long ossId);
-
-    SysOssVo upload(MultipartFile file);
-
-    void download(Long ossId, HttpServletResponse response) throws IOException;
-
-    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPermissionService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPermissionService.java
deleted file mode 100644
index 1e6d2d1..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPermissionService.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.ruoyi.system.service;
-
-import java.util.Set;
-
-/**
- * 鐢ㄦ埛鏉冮檺澶勭悊
- *
- * @author Lion Li
- */
-public interface ISysPermissionService {
-
-    /**
-     * 鑾峰彇瑙掕壊鏁版嵁鏉冮檺
-     *
-     * @param userId  鐢ㄦ埛id
-     * @return 瑙掕壊鏉冮檺淇℃伅
-     */
-    Set<String> getRolePermission(Long userId);
-
-    /**
-     * 鑾峰彇鑿滃崟鏁版嵁鏉冮檺
-     *
-     * @param userId  鐢ㄦ埛id
-     * @return 鑿滃崟鏉冮檺淇℃伅
-     */
-    Set<String> getMenuPermission(Long userId);
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPostService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPostService.java
deleted file mode 100644
index 5110466..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPostService.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package com.ruoyi.system.service;
-
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.system.domain.bo.SysPostBo;
-import com.ruoyi.system.domain.vo.SysPostVo;
-
-import java.util.List;
-
-/**
- * 宀椾綅淇℃伅 鏈嶅姟灞�
- *
- * @author Lion Li
- */
-public interface ISysPostService {
-
-
-    TableDataInfo<SysPostVo> selectPagePostList(SysPostBo post, PageQuery pageQuery);
-
-    /**
-     * 鏌ヨ宀椾綅淇℃伅闆嗗悎
-     *
-     * @param post 宀椾綅淇℃伅
-     * @return 宀椾綅鍒楄〃
-     */
-    List<SysPostVo> selectPostList(SysPostBo post);
-
-    /**
-     * 鏌ヨ鎵�鏈夊矖浣�
-     *
-     * @return 宀椾綅鍒楄〃
-     */
-    List<SysPostVo> selectPostAll();
-
-    /**
-     * 閫氳繃宀椾綅ID鏌ヨ宀椾綅淇℃伅
-     *
-     * @param postId 宀椾綅ID
-     * @return 瑙掕壊瀵硅薄淇℃伅
-     */
-    SysPostVo selectPostById(Long postId);
-
-    /**
-     * 鏍规嵁鐢ㄦ埛ID鑾峰彇宀椾綅閫夋嫨妗嗗垪琛�
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 閫変腑宀椾綅ID鍒楄〃
-     */
-    List<Long> selectPostListByUserId(Long userId);
-
-    /**
-     * 鏍¢獙宀椾綅鍚嶇О
-     *
-     * @param post 宀椾綅淇℃伅
-     * @return 缁撴灉
-     */
-    boolean checkPostNameUnique(SysPostBo post);
-
-    /**
-     * 鏍¢獙宀椾綅缂栫爜
-     *
-     * @param post 宀椾綅淇℃伅
-     * @return 缁撴灉
-     */
-    boolean checkPostCodeUnique(SysPostBo post);
-
-    /**
-     * 閫氳繃宀椾綅ID鏌ヨ宀椾綅浣跨敤鏁伴噺
-     *
-     * @param postId 宀椾綅ID
-     * @return 缁撴灉
-     */
-    long countUserPostById(Long postId);
-
-    /**
-     * 鍒犻櫎宀椾綅淇℃伅
-     *
-     * @param postId 宀椾綅ID
-     * @return 缁撴灉
-     */
-    int deletePostById(Long postId);
-
-    /**
-     * 鎵归噺鍒犻櫎宀椾綅淇℃伅
-     *
-     * @param postIds 闇�瑕佸垹闄ょ殑宀椾綅ID
-     * @return 缁撴灉
-     */
-    int deletePostByIds(Long[] postIds);
-
-    /**
-     * 鏂板淇濆瓨宀椾綅淇℃伅
-     *
-     * @param bo 宀椾綅淇℃伅
-     * @return 缁撴灉
-     */
-    int insertPost(SysPostBo bo);
-
-    /**
-     * 淇敼淇濆瓨宀椾綅淇℃伅
-     *
-     * @param bo 宀椾綅淇℃伅
-     * @return 缁撴灉
-     */
-    int updatePost(SysPostBo bo);
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java
deleted file mode 100644
index 0f852fe..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java
+++ /dev/null
@@ -1,181 +0,0 @@
-package com.ruoyi.system.service;
-
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.system.domain.SysUserRole;
-import com.ruoyi.system.domain.bo.SysRoleBo;
-import com.ruoyi.system.domain.vo.SysRoleVo;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * 瑙掕壊涓氬姟灞�
- *
- * @author Lion Li
- */
-public interface ISysRoleService {
-
-
-    TableDataInfo<SysRoleVo> selectPageRoleList(SysRoleBo role, PageQuery pageQuery);
-
-    /**
-     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瑙掕壊鏁版嵁
-     *
-     * @param role 瑙掕壊淇℃伅
-     * @return 瑙掕壊鏁版嵁闆嗗悎淇℃伅
-     */
-    List<SysRoleVo> selectRoleList(SysRoleBo role);
-
-    /**
-     * 鏍规嵁鐢ㄦ埛ID鏌ヨ瑙掕壊鍒楄〃
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 瑙掕壊鍒楄〃
-     */
-    List<SysRoleVo> selectRolesByUserId(Long userId);
-
-    /**
-     * 鏍规嵁鐢ㄦ埛ID鏌ヨ瑙掕壊鏉冮檺
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 鏉冮檺鍒楄〃
-     */
-    Set<String> selectRolePermissionByUserId(Long userId);
-
-    /**
-     * 鏌ヨ鎵�鏈夎鑹�
-     *
-     * @return 瑙掕壊鍒楄〃
-     */
-    List<SysRoleVo> selectRoleAll();
-
-    /**
-     * 鏍规嵁鐢ㄦ埛ID鑾峰彇瑙掕壊閫夋嫨妗嗗垪琛�
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 閫変腑瑙掕壊ID鍒楄〃
-     */
-    List<Long> selectRoleListByUserId(Long userId);
-
-    /**
-     * 閫氳繃瑙掕壊ID鏌ヨ瑙掕壊
-     *
-     * @param roleId 瑙掕壊ID
-     * @return 瑙掕壊瀵硅薄淇℃伅
-     */
-    SysRoleVo selectRoleById(Long roleId);
-
-    /**
-     * 鏍¢獙瑙掕壊鍚嶇О鏄惁鍞竴
-     *
-     * @param role 瑙掕壊淇℃伅
-     * @return 缁撴灉
-     */
-    boolean checkRoleNameUnique(SysRoleBo role);
-
-    /**
-     * 鏍¢獙瑙掕壊鏉冮檺鏄惁鍞竴
-     *
-     * @param role 瑙掕壊淇℃伅
-     * @return 缁撴灉
-     */
-    boolean checkRoleKeyUnique(SysRoleBo role);
-
-    /**
-     * 鏍¢獙瑙掕壊鏄惁鍏佽鎿嶄綔
-     *
-     * @param roleId 瑙掕壊ID
-     */
-    void checkRoleAllowed(Long roleId);
-
-    /**
-     * 鏍¢獙瑙掕壊鏄惁鏈夋暟鎹潈闄�
-     *
-     * @param roleId 瑙掕壊id
-     */
-    void checkRoleDataScope(Long roleId);
-
-    /**
-     * 閫氳繃瑙掕壊ID鏌ヨ瑙掕壊浣跨敤鏁伴噺
-     *
-     * @param roleId 瑙掕壊ID
-     * @return 缁撴灉
-     */
-    long countUserRoleByRoleId(Long roleId);
-
-    /**
-     * 鏂板淇濆瓨瑙掕壊淇℃伅
-     *
-     * @param bo 瑙掕壊淇℃伅
-     * @return 缁撴灉
-     */
-    int insertRole(SysRoleBo bo);
-
-    /**
-     * 淇敼淇濆瓨瑙掕壊淇℃伅
-     *
-     * @param bo 瑙掕壊淇℃伅
-     * @return 缁撴灉
-     */
-    int updateRole(SysRoleBo bo);
-
-    /**
-     * 淇敼瑙掕壊鐘舵��
-     *
-     * @param roleId 瑙掕壊ID
-     * @param status 瑙掕壊鐘舵��
-     * @return 缁撴灉
-     */
-    int updateRoleStatus(Long roleId, String status);
-
-    /**
-     * 淇敼鏁版嵁鏉冮檺淇℃伅
-     *
-     * @param bo 瑙掕壊淇℃伅
-     * @return 缁撴灉
-     */
-    int authDataScope(SysRoleBo bo);
-
-    /**
-     * 閫氳繃瑙掕壊ID鍒犻櫎瑙掕壊
-     *
-     * @param roleId 瑙掕壊ID
-     * @return 缁撴灉
-     */
-    int deleteRoleById(Long roleId);
-
-    /**
-     * 鎵归噺鍒犻櫎瑙掕壊淇℃伅
-     *
-     * @param roleIds 闇�瑕佸垹闄ょ殑瑙掕壊ID
-     * @return 缁撴灉
-     */
-    int deleteRoleByIds(Long[] roleIds);
-
-    /**
-     * 鍙栨秷鎺堟潈鐢ㄦ埛瑙掕壊
-     *
-     * @param userRole 鐢ㄦ埛鍜岃鑹插叧鑱斾俊鎭�
-     * @return 缁撴灉
-     */
-    int deleteAuthUser(SysUserRole userRole);
-
-    /**
-     * 鎵归噺鍙栨秷鎺堟潈鐢ㄦ埛瑙掕壊
-     *
-     * @param roleId  瑙掕壊ID
-     * @param userIds 闇�瑕佸彇娑堟巿鏉冪殑鐢ㄦ埛鏁版嵁ID
-     * @return 缁撴灉
-     */
-    int deleteAuthUsers(Long roleId, Long[] userIds);
-
-    /**
-     * 鎵归噺閫夋嫨鎺堟潈鐢ㄦ埛瑙掕壊
-     *
-     * @param roleId  瑙掕壊ID
-     * @param userIds 闇�瑕佸垹闄ょ殑鐢ㄦ埛鏁版嵁ID
-     * @return 缁撴灉
-     */
-    int insertAuthUsers(Long roleId, Long[] userIds);
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTenantPackageService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTenantPackageService.java
deleted file mode 100644
index 629e893..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTenantPackageService.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.ruoyi.system.service;
-
-import com.ruoyi.system.domain.vo.SysTenantPackageVo;
-import com.ruoyi.system.domain.bo.SysTenantPackageBo;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * 绉熸埛濂楅Service鎺ュ彛
- *
- * @author Michelle.Chung
- */
-public interface ISysTenantPackageService {
-
-    /**
-     * 鏌ヨ绉熸埛濂楅
-     */
-    SysTenantPackageVo queryById(Long packageId);
-
-    /**
-     * 鏌ヨ绉熸埛濂楅鍒楄〃
-     */
-    TableDataInfo<SysTenantPackageVo> queryPageList(SysTenantPackageBo bo, PageQuery pageQuery);
-
-    /**
-     * 鏌ヨ绉熸埛濂楅鍒楄〃
-     */
-    List<SysTenantPackageVo> queryList(SysTenantPackageBo bo);
-
-    /**
-     * 鏂板绉熸埛濂楅
-     */
-    Boolean insertByBo(SysTenantPackageBo bo);
-
-    /**
-     * 淇敼绉熸埛濂楅
-     */
-    Boolean updateByBo(SysTenantPackageBo bo);
-
-    /**
-     * 淇敼濂楅鐘舵��
-     */
-    int updatePackageStatus(SysTenantPackageBo bo);
-
-    /**
-     * 鏍¢獙骞舵壒閲忓垹闄ょ鎴峰椁愪俊鎭�
-     */
-    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTenantService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTenantService.java
deleted file mode 100644
index 5cef033..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTenantService.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package com.ruoyi.system.service;
-
-import com.ruoyi.system.domain.vo.SysTenantVo;
-import com.ruoyi.system.domain.bo.SysTenantBo;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * 绉熸埛Service鎺ュ彛
- *
- * @author Michelle.Chung
- */
-public interface ISysTenantService {
-
-    /**
-     * 鏌ヨ绉熸埛
-     */
-    SysTenantVo queryById(Long id);
-
-    /**
-     * 鍩轰簬绉熸埛ID鏌ヨ绉熸埛
-     */
-    SysTenantVo queryByTenantId(String tenantId);
-
-    /**
-     * 鏌ヨ绉熸埛鍒楄〃
-     */
-    TableDataInfo<SysTenantVo> queryPageList(SysTenantBo bo, PageQuery pageQuery);
-
-    /**
-     * 鏌ヨ绉熸埛鍒楄〃
-     */
-    List<SysTenantVo> queryList(SysTenantBo bo);
-
-    /**
-     * 鏂板绉熸埛
-     */
-    Boolean insertByBo(SysTenantBo bo);
-
-    /**
-     * 淇敼绉熸埛
-     */
-    Boolean updateByBo(SysTenantBo bo);
-
-    /**
-     * 淇敼绉熸埛鐘舵��
-     */
-    int updateTenantStatus(SysTenantBo bo);
-
-    /**
-     * 鏍¢獙绉熸埛鏄惁鍏佽鎿嶄綔
-     */
-    void checkTenantAllowed(String tenantId);
-
-    /**
-     * 鏍¢獙骞舵壒閲忓垹闄ょ鎴蜂俊鎭�
-     */
-    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
-
-    /**
-     * 鏍¢獙浼佷笟鍚嶇О鏄惁鍞竴
-     */
-    boolean checkCompanyNameUnique(SysTenantBo bo);
-
-    /**
-     * 鏍¢獙璐﹀彿浣欓
-     */
-    boolean checkAccountBalance(String tenantId);
-
-    /**
-     * 鏍¢獙鏈夋晥鏈�
-     */
-    boolean checkExpireTime(String tenantId);
-
-    /**
-     * 鍚屾绉熸埛濂楅
-     */
-    Boolean syncTenantPackage(String tenantId, String packageId);
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
deleted file mode 100644
index ed1afdd..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
+++ /dev/null
@@ -1,205 +0,0 @@
-package com.ruoyi.system.service;
-
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.system.domain.bo.SysUserBo;
-import com.ruoyi.system.domain.vo.SysUserVo;
-
-import java.util.List;
-
-/**
- * 鐢ㄦ埛 涓氬姟灞�
- *
- * @author Lion Li
- */
-public interface ISysUserService {
-
-
-    TableDataInfo<SysUserVo> selectPageUserList(SysUserBo user, PageQuery pageQuery);
-
-    /**
-     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ鐢ㄦ埛鍒楄〃
-     *
-     * @param user 鐢ㄦ埛淇℃伅
-     * @return 鐢ㄦ埛淇℃伅闆嗗悎淇℃伅
-     */
-    List<SysUserVo> selectUserList(SysUserBo user);
-
-    /**
-     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ宸插垎閰嶇敤鎴疯鑹插垪琛�
-     *
-     * @param user 鐢ㄦ埛淇℃伅
-     * @return 鐢ㄦ埛淇℃伅闆嗗悎淇℃伅
-     */
-    TableDataInfo<SysUserVo> selectAllocatedList(SysUserBo user, PageQuery pageQuery);
-
-    /**
-     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ鏈垎閰嶇敤鎴疯鑹插垪琛�
-     *
-     * @param user 鐢ㄦ埛淇℃伅
-     * @return 鐢ㄦ埛淇℃伅闆嗗悎淇℃伅
-     */
-    TableDataInfo<SysUserVo> selectUnallocatedList(SysUserBo user, PageQuery pageQuery);
-
-    /**
-     * 閫氳繃鐢ㄦ埛鍚嶆煡璇㈢敤鎴�
-     *
-     * @param userName 鐢ㄦ埛鍚�
-     * @return 鐢ㄦ埛瀵硅薄淇℃伅
-     */
-    SysUserVo selectUserByUserName(String userName);
-
-    /**
-     * 閫氳繃鎵嬫満鍙锋煡璇㈢敤鎴�
-     *
-     * @param phonenumber 鎵嬫満鍙�
-     * @return 鐢ㄦ埛瀵硅薄淇℃伅
-     */
-    SysUserVo selectUserByPhonenumber(String phonenumber);
-
-    /**
-     * 閫氳繃鐢ㄦ埛ID鏌ヨ鐢ㄦ埛
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 鐢ㄦ埛瀵硅薄淇℃伅
-     */
-    SysUserVo selectUserById(Long userId);
-
-    /**
-     * 鏍规嵁鐢ㄦ埛ID鏌ヨ鐢ㄦ埛鎵�灞炶鑹茬粍
-     *
-     * @param userName 鐢ㄦ埛鍚�
-     * @return 缁撴灉
-     */
-    String selectUserRoleGroup(String userName);
-
-    /**
-     * 鏍规嵁鐢ㄦ埛ID鏌ヨ鐢ㄦ埛鎵�灞炲矖浣嶇粍
-     *
-     * @param userName 鐢ㄦ埛鍚�
-     * @return 缁撴灉
-     */
-    String selectUserPostGroup(String userName);
-
-    /**
-     * 鏍¢獙鐢ㄦ埛鍚嶇О鏄惁鍞竴
-     *
-     * @param user 鐢ㄦ埛淇℃伅
-     * @return 缁撴灉
-     */
-    boolean checkUserNameUnique(SysUserBo user);
-
-    /**
-     * 鏍¢獙鎵嬫満鍙风爜鏄惁鍞竴
-     *
-     * @param user 鐢ㄦ埛淇℃伅
-     * @return 缁撴灉
-     */
-    boolean checkPhoneUnique(SysUserBo user);
-
-    /**
-     * 鏍¢獙email鏄惁鍞竴
-     *
-     * @param user 鐢ㄦ埛淇℃伅
-     * @return 缁撴灉
-     */
-    boolean checkEmailUnique(SysUserBo user);
-
-    /**
-     * 鏍¢獙鐢ㄦ埛鏄惁鍏佽鎿嶄綔
-     *
-     * @param userId 鐢ㄦ埛ID
-     */
-    void checkUserAllowed(Long userId);
-
-    /**
-     * 鏍¢獙鐢ㄦ埛鏄惁鏈夋暟鎹潈闄�
-     *
-     * @param userId 鐢ㄦ埛id
-     */
-    void checkUserDataScope(Long userId);
-
-    /**
-     * 鏂板鐢ㄦ埛淇℃伅
-     *
-     * @param user 鐢ㄦ埛淇℃伅
-     * @return 缁撴灉
-     */
-    int insertUser(SysUserBo user);
-
-    /**
-     * 娉ㄥ唽鐢ㄦ埛淇℃伅
-     *
-     * @param user 鐢ㄦ埛淇℃伅
-     * @return 缁撴灉
-     */
-    boolean registerUser(SysUserBo user, String tenantId);
-
-    /**
-     * 淇敼鐢ㄦ埛淇℃伅
-     *
-     * @param user 鐢ㄦ埛淇℃伅
-     * @return 缁撴灉
-     */
-    int updateUser(SysUserBo user);
-
-    /**
-     * 鐢ㄦ埛鎺堟潈瑙掕壊
-     *
-     * @param userId  鐢ㄦ埛ID
-     * @param roleIds 瑙掕壊缁�
-     */
-    void insertUserAuth(Long userId, Long[] roleIds);
-
-    /**
-     * 淇敼鐢ㄦ埛鐘舵��
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @param status 甯愬彿鐘舵��
-     * @return 缁撴灉
-     */
-    int updateUserStatus(Long userId, String status);
-
-    /**
-     * 淇敼鐢ㄦ埛鍩烘湰淇℃伅
-     *
-     * @param user 鐢ㄦ埛淇℃伅
-     * @return 缁撴灉
-     */
-    int updateUserProfile(SysUserBo user);
-
-    /**
-     * 淇敼鐢ㄦ埛澶村儚
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @param avatar 澶村儚鍦板潃
-     * @return 缁撴灉
-     */
-    boolean updateUserAvatar(Long userId, Long avatar);
-
-    /**
-     * 閲嶇疆鐢ㄦ埛瀵嗙爜
-     *
-     * @param userId   鐢ㄦ埛ID
-     * @param password 瀵嗙爜
-     * @return 缁撴灉
-     */
-    int resetUserPwd(Long userId, String password);
-
-    /**
-     * 閫氳繃鐢ㄦ埛ID鍒犻櫎鐢ㄦ埛
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 缁撴灉
-     */
-    int deleteUserById(Long userId);
-
-    /**
-     * 鎵归噺鍒犻櫎鐢ㄦ埛淇℃伅
-     *
-     * @param userIds 闇�瑕佸垹闄ょ殑鐢ㄦ埛ID
-     * @return 缁撴灉
-     */
-    int deleteUserByIds(Long[] userIds);
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java
deleted file mode 100644
index b64d85d..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java
+++ /dev/null
@@ -1,216 +0,0 @@
-package com.ruoyi.system.service.impl;
-
-import cn.hutool.core.convert.Convert;
-import cn.hutool.core.util.ObjectUtil;
-import com.baomidou.dynamic.datasource.annotation.DS;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.core.constant.CacheNames;
-import com.ruoyi.common.core.constant.UserConstants;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.service.ConfigService;
-import com.ruoyi.common.core.utils.MapstructUtils;
-import com.ruoyi.common.core.utils.SpringUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.redis.utils.CacheUtils;
-import com.ruoyi.common.tenant.helper.TenantHelper;
-import com.ruoyi.system.domain.SysConfig;
-import com.ruoyi.system.domain.bo.SysConfigBo;
-import com.ruoyi.system.domain.vo.SysConfigVo;
-import com.ruoyi.system.mapper.SysConfigMapper;
-import com.ruoyi.system.service.ISysConfigService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.cache.annotation.CachePut;
-import org.springframework.cache.annotation.Cacheable;
-import org.springframework.stereotype.Service;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 鍙傛暟閰嶇疆 鏈嶅姟灞傚疄鐜�
- *
- * @author Lion Li
- */
-@RequiredArgsConstructor
-@Service
-public class SysConfigServiceImpl implements ISysConfigService, ConfigService {
-
-    private final SysConfigMapper baseMapper;
-
-    @Override
-    public TableDataInfo<SysConfigVo> selectPageConfigList(SysConfigBo config, PageQuery pageQuery) {
-        LambdaQueryWrapper<SysConfig> lqw = buildQueryWrapper(config);
-        Page<SysConfigVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw);
-        return TableDataInfo.build(page);
-    }
-
-    /**
-     * 鏌ヨ鍙傛暟閰嶇疆淇℃伅
-     *
-     * @param configId 鍙傛暟閰嶇疆ID
-     * @return 鍙傛暟閰嶇疆淇℃伅
-     */
-    @Override
-    @DS("master")
-    public SysConfigVo selectConfigById(Long configId) {
-        return baseMapper.selectVoById(configId);
-    }
-
-    /**
-     * 鏍规嵁閿悕鏌ヨ鍙傛暟閰嶇疆淇℃伅
-     *
-     * @param configKey 鍙傛暟key
-     * @return 鍙傛暟閿��
-     */
-    @Cacheable(cacheNames = CacheNames.SYS_CONFIG, key = "#configKey")
-    @Override
-    public String selectConfigByKey(String configKey) {
-        SysConfig retConfig = baseMapper.selectOne(new LambdaQueryWrapper<SysConfig>()
-            .eq(SysConfig::getConfigKey, configKey));
-        if (ObjectUtil.isNotNull(retConfig)) {
-            return retConfig.getConfigValue();
-        }
-        return StringUtils.EMPTY;
-    }
-
-    /**
-     * 鑾峰彇娉ㄥ唽寮�鍏�
-     * @param tenantId 绉熸埛id
-     * @return true寮�鍚紝false鍏抽棴
-     */
-    @Override
-    public boolean selectRegisterEnabled(String tenantId) {
-        SysConfig retConfig = baseMapper.selectOne(new LambdaQueryWrapper<SysConfig>()
-            .eq(SysConfig::getConfigKey, "sys.account.registerUser")
-            .eq(TenantHelper.isEnable(),SysConfig::getTenantId, tenantId));
-        if (ObjectUtil.isNull(retConfig)) {
-            return false;
-        }
-        return Convert.toBool(retConfig.getConfigValue());
-    }
-
-    /**
-     * 鏌ヨ鍙傛暟閰嶇疆鍒楄〃
-     *
-     * @param config 鍙傛暟閰嶇疆淇℃伅
-     * @return 鍙傛暟閰嶇疆闆嗗悎
-     */
-    @Override
-    public List<SysConfigVo> selectConfigList(SysConfigBo config) {
-        LambdaQueryWrapper<SysConfig> lqw = buildQueryWrapper(config);
-        return baseMapper.selectVoList(lqw);
-    }
-
-    private LambdaQueryWrapper<SysConfig> buildQueryWrapper(SysConfigBo bo) {
-        Map<String, Object> params = bo.getParams();
-        LambdaQueryWrapper<SysConfig> lqw = Wrappers.lambdaQuery();
-        lqw.like(StringUtils.isNotBlank(bo.getConfigName()), SysConfig::getConfigName, bo.getConfigName());
-        lqw.eq(StringUtils.isNotBlank(bo.getConfigType()), SysConfig::getConfigType, bo.getConfigType());
-        lqw.like(StringUtils.isNotBlank(bo.getConfigKey()), SysConfig::getConfigKey, bo.getConfigKey());
-        lqw.between(params.get("beginTime") != null && params.get("endTime") != null,
-            SysConfig::getCreateTime, params.get("beginTime"), params.get("endTime"));
-        return lqw;
-    }
-
-    /**
-     * 鏂板鍙傛暟閰嶇疆
-     *
-     * @param bo 鍙傛暟閰嶇疆淇℃伅
-     * @return 缁撴灉
-     */
-    @CachePut(cacheNames = CacheNames.SYS_CONFIG, key = "#bo.configKey")
-    @Override
-    public String insertConfig(SysConfigBo bo) {
-        SysConfig config = MapstructUtils.convert(bo, SysConfig.class);
-        int row = baseMapper.insert(config);
-        if (row > 0) {
-            return config.getConfigValue();
-        }
-        throw new ServiceException("鎿嶄綔澶辫触");
-    }
-
-    /**
-     * 淇敼鍙傛暟閰嶇疆
-     *
-     * @param bo 鍙傛暟閰嶇疆淇℃伅
-     * @return 缁撴灉
-     */
-    @CachePut(cacheNames = CacheNames.SYS_CONFIG, key = "#bo.configKey")
-    @Override
-    public String updateConfig(SysConfigBo bo) {
-        int row = 0;
-        SysConfig config = MapstructUtils.convert(bo, SysConfig.class);
-        if (config.getConfigId() != null) {
-            SysConfig temp = baseMapper.selectById(config.getConfigId());
-            if (!StringUtils.equals(temp.getConfigKey(), config.getConfigKey())) {
-                CacheUtils.evict(CacheNames.SYS_CONFIG, temp.getConfigKey());
-            }
-            row = baseMapper.updateById(config);
-        } else {
-            row = baseMapper.update(config, new LambdaQueryWrapper<SysConfig>()
-                .eq(SysConfig::getConfigKey, config.getConfigKey()));
-        }
-        if (row > 0) {
-            return config.getConfigValue();
-        }
-        throw new ServiceException("鎿嶄綔澶辫触");
-    }
-
-    /**
-     * 鎵归噺鍒犻櫎鍙傛暟淇℃伅
-     *
-     * @param configIds 闇�瑕佸垹闄ょ殑鍙傛暟ID
-     */
-    @Override
-    public void deleteConfigByIds(Long[] configIds) {
-        for (Long configId : configIds) {
-            SysConfig config = baseMapper.selectById(configId);
-            if (StringUtils.equals(UserConstants.YES, config.getConfigType())) {
-                throw new ServiceException(String.format("鍐呯疆鍙傛暟銆�%1$s銆戜笉鑳藉垹闄� ", config.getConfigKey()));
-            }
-            CacheUtils.evict(CacheNames.SYS_CONFIG, config.getConfigKey());
-        }
-        baseMapper.deleteBatchIds(Arrays.asList(configIds));
-    }
-
-    /**
-     * 閲嶇疆鍙傛暟缂撳瓨鏁版嵁
-     */
-    @Override
-    public void resetConfigCache() {
-        CacheUtils.clear(CacheNames.SYS_CONFIG);
-    }
-
-    /**
-     * 鏍¢獙鍙傛暟閿悕鏄惁鍞竴
-     *
-     * @param config 鍙傛暟閰嶇疆淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    public boolean checkConfigKeyUnique(SysConfigBo config) {
-        long configId = ObjectUtil.isNull(config.getConfigId()) ? -1L : config.getConfigId();
-        SysConfig info = baseMapper.selectOne(new LambdaQueryWrapper<SysConfig>().eq(SysConfig::getConfigKey, config.getConfigKey()));
-        if (ObjectUtil.isNotNull(info) && info.getConfigId() != configId) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * 鏍规嵁鍙傛暟 key 鑾峰彇鍙傛暟鍊�
-     *
-     * @param configKey 鍙傛暟 key
-     * @return 鍙傛暟鍊�
-     */
-    @Override
-    public String getConfigValue(String configKey) {
-        return SpringUtils.getAopProxy(this).selectConfigByKey(configKey);
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDataScopeServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDataScopeServiceImpl.java
deleted file mode 100644
index 7a75ae3..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDataScopeServiceImpl.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.ruoyi.system.service.impl;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.convert.Convert;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.ruoyi.system.domain.SysDept;
-import com.ruoyi.common.mybatis.helper.DataBaseHelper;
-import com.ruoyi.common.core.utils.StreamUtils;
-import com.ruoyi.system.domain.SysRoleDept;
-import com.ruoyi.system.mapper.SysDeptMapper;
-import com.ruoyi.system.mapper.SysRoleDeptMapper;
-import com.ruoyi.system.service.ISysDataScopeService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-
-/**
- * 鏁版嵁鏉冮檺 瀹炵幇
- * <p>
- * 娉ㄦ剰: 姝ervice鍐呬笉鍏佽璋冪敤鏍囨敞`鏁版嵁鏉冮檺`娉ㄨВ鐨勬柟娉�
- * 渚嬪: deptMapper.selectList 姝� selectList 鏂规硶鏍囨敞浜哷鏁版嵁鏉冮檺`娉ㄨВ 浼氬嚭鐜板惊鐜В鏋愮殑闂
- *
- * @author Lion Li
- */
-@RequiredArgsConstructor
-@Service("sdss")
-public class SysDataScopeServiceImpl implements ISysDataScopeService {
-
-    private final SysRoleDeptMapper roleDeptMapper;
-    private final SysDeptMapper deptMapper;
-
-    @Override
-    public String getRoleCustom(Long roleId) {
-        List<SysRoleDept> list = roleDeptMapper.selectList(
-            new LambdaQueryWrapper<SysRoleDept>()
-                .select(SysRoleDept::getDeptId)
-                .eq(SysRoleDept::getRoleId, roleId));
-        if (CollUtil.isNotEmpty(list)) {
-            return StreamUtils.join(list, rd -> Convert.toStr(rd.getDeptId()));
-        }
-        return null;
-    }
-
-    @Override
-    public String getDeptAndChild(Long deptId) {
-        List<SysDept> deptList = deptMapper.selectList(new LambdaQueryWrapper<SysDept>()
-            .select(SysDept::getDeptId)
-            .apply(DataBaseHelper.findInSet(deptId, "ancestors")));
-        List<Long> ids = StreamUtils.toList(deptList, SysDept::getDeptId);
-        ids.add(deptId);
-        List<SysDept> list = deptMapper.selectList(new LambdaQueryWrapper<SysDept>()
-            .select(SysDept::getDeptId)
-            .in(SysDept::getDeptId, ids));
-        if (CollUtil.isNotEmpty(list)) {
-            return StreamUtils.join(list, d -> Convert.toStr(d.getDeptId()));
-        }
-        return null;
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java
deleted file mode 100644
index 43b895a..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java
+++ /dev/null
@@ -1,325 +0,0 @@
-package com.ruoyi.system.service.impl;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.convert.Convert;
-import cn.hutool.core.lang.tree.Tree;
-import cn.hutool.core.util.ObjectUtil;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.ruoyi.common.core.constant.CacheNames;
-import com.ruoyi.common.core.constant.UserConstants;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.service.DeptService;
-import com.ruoyi.common.core.utils.MapstructUtils;
-import com.ruoyi.common.core.utils.SpringUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.core.utils.TreeBuildUtils;
-import com.ruoyi.common.mybatis.helper.DataBaseHelper;
-import com.ruoyi.common.redis.utils.CacheUtils;
-import com.ruoyi.common.satoken.utils.LoginHelper;
-import com.ruoyi.system.domain.SysDept;
-import com.ruoyi.system.domain.SysRole;
-import com.ruoyi.system.domain.SysUser;
-import com.ruoyi.system.domain.bo.SysDeptBo;
-import com.ruoyi.system.domain.vo.SysDeptVo;
-import com.ruoyi.system.mapper.SysDeptMapper;
-import com.ruoyi.system.mapper.SysRoleMapper;
-import com.ruoyi.system.mapper.SysUserMapper;
-import com.ruoyi.system.service.ISysDeptService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.cache.annotation.CacheEvict;
-import org.springframework.cache.annotation.Cacheable;
-import org.springframework.stereotype.Service;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * 閮ㄩ棬绠$悊 鏈嶅姟瀹炵幇
- *
- * @author Lion Li
- */
-@RequiredArgsConstructor
-@Service
-public class SysDeptServiceImpl implements ISysDeptService, DeptService {
-
-    private final SysDeptMapper baseMapper;
-    private final SysRoleMapper roleMapper;
-    private final SysUserMapper userMapper;
-
-    /**
-     * 鏌ヨ閮ㄩ棬绠$悊鏁版嵁
-     *
-     * @param dept 閮ㄩ棬淇℃伅
-     * @return 閮ㄩ棬淇℃伅闆嗗悎
-     */
-    @Override
-    public List<SysDeptVo> selectDeptList(SysDeptBo dept) {
-        LambdaQueryWrapper<SysDept> lqw = buildQueryWrapper(dept);
-        return baseMapper.selectDeptList(lqw);
-    }
-
-    /**
-     * 鏌ヨ閮ㄩ棬鏍戠粨鏋勪俊鎭�
-     *
-     * @param bo 閮ㄩ棬淇℃伅
-     * @return 閮ㄩ棬鏍戜俊鎭泦鍚�
-     */
-    @Override
-    public List<Tree<Long>> selectDeptTreeList(SysDeptBo bo) {
-        LambdaQueryWrapper<SysDept> lqw = buildQueryWrapper(bo);
-        List<SysDept> depts = baseMapper.selectList(lqw);
-        return buildDeptTreeSelect(depts);
-    }
-
-    private LambdaQueryWrapper<SysDept> buildQueryWrapper(SysDeptBo bo) {
-        LambdaQueryWrapper<SysDept> lqw = Wrappers.lambdaQuery();
-        lqw.eq(SysDept::getDelFlag, "0");
-        lqw.eq(ObjectUtil.isNotNull(bo.getDeptId()), SysDept::getDeptId, bo.getDeptId());
-        lqw.eq(ObjectUtil.isNotNull(bo.getParentId()), SysDept::getParentId, bo.getParentId());
-        lqw.like(StringUtils.isNotBlank(bo.getDeptName()), SysDept::getDeptName, bo.getDeptName());
-        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysDept::getStatus, bo.getStatus());
-        lqw.orderByAsc(SysDept::getParentId);
-        lqw.orderByAsc(SysDept::getOrderNum);
-        return lqw;
-    }
-
-    /**
-     * 鏋勫缓鍓嶇鎵�闇�瑕佷笅鎷夋爲缁撴瀯
-     *
-     * @param depts 閮ㄩ棬鍒楄〃
-     * @return 涓嬫媺鏍戠粨鏋勫垪琛�
-     */
-    @Override
-    public List<Tree<Long>> buildDeptTreeSelect(List<SysDept> depts) {
-        if (CollUtil.isEmpty(depts)) {
-            return CollUtil.newArrayList();
-        }
-        return TreeBuildUtils.build(depts, (dept, tree) ->
-            tree.setId(dept.getDeptId())
-                .setParentId(dept.getParentId())
-                .setName(dept.getDeptName())
-                .setWeight(dept.getOrderNum()));
-    }
-
-    /**
-     * 鏍规嵁瑙掕壊ID鏌ヨ閮ㄩ棬鏍戜俊鎭�
-     *
-     * @param roleId 瑙掕壊ID
-     * @return 閫変腑閮ㄩ棬鍒楄〃
-     */
-    @Override
-    public List<Long> selectDeptListByRoleId(Long roleId) {
-        SysRole role = roleMapper.selectById(roleId);
-        return baseMapper.selectDeptListByRoleId(roleId, role.getDeptCheckStrictly());
-    }
-
-    /**
-     * 鏍规嵁閮ㄩ棬ID鏌ヨ淇℃伅
-     *
-     * @param deptId 閮ㄩ棬ID
-     * @return 閮ㄩ棬淇℃伅
-     */
-    @Cacheable(cacheNames = CacheNames.SYS_DEPT, key = "#deptId")
-    @Override
-    public SysDeptVo selectDeptById(Long deptId) {
-        SysDeptVo dept = baseMapper.selectVoById(deptId);
-        if (ObjectUtil.isNull(dept)) {
-            return null;
-        }
-        SysDeptVo parentDept = baseMapper.selectVoOne(new LambdaQueryWrapper<SysDept>()
-            .select(SysDept::getDeptName).eq(SysDept::getDeptId, dept.getParentId()));
-        dept.setParentName(ObjectUtil.isNotNull(parentDept) ? parentDept.getDeptName() : null);
-        return dept;
-    }
-
-    /**
-     * 閫氳繃閮ㄩ棬ID鏌ヨ閮ㄩ棬鍚嶇О
-     *
-     * @param deptIds 閮ㄩ棬ID涓查�楀彿鍒嗛殧
-     * @return 閮ㄩ棬鍚嶇О涓查�楀彿鍒嗛殧
-     */
-    @Override
-    public String selectDeptNameByIds(String deptIds) {
-        List<String> list = new ArrayList<>();
-        for (Long id : StringUtils.splitTo(deptIds, Convert::toLong)) {
-            SysDeptVo vo = SpringUtils.getAopProxy(this).selectDeptById(id);
-            if (ObjectUtil.isNotNull(vo)) {
-                list.add(vo.getDeptName());
-            }
-        }
-        return String.join(StringUtils.SEPARATOR, list);
-    }
-
-    /**
-     * 鏍规嵁ID鏌ヨ鎵�鏈夊瓙閮ㄩ棬鏁帮紙姝e父鐘舵�侊級
-     *
-     * @param deptId 閮ㄩ棬ID
-     * @return 瀛愰儴闂ㄦ暟
-     */
-    @Override
-    public long selectNormalChildrenDeptById(Long deptId) {
-        return baseMapper.selectCount(new LambdaQueryWrapper<SysDept>()
-            .eq(SysDept::getStatus, UserConstants.DEPT_NORMAL)
-            .apply(DataBaseHelper.findInSet(deptId, "ancestors")));
-    }
-
-    /**
-     * 鏄惁瀛樺湪瀛愯妭鐐�
-     *
-     * @param deptId 閮ㄩ棬ID
-     * @return 缁撴灉
-     */
-    @Override
-    public boolean hasChildByDeptId(Long deptId) {
-        return baseMapper.exists(new LambdaQueryWrapper<SysDept>()
-            .eq(SysDept::getParentId, deptId));
-    }
-
-    /**
-     * 鏌ヨ閮ㄩ棬鏄惁瀛樺湪鐢ㄦ埛
-     *
-     * @param deptId 閮ㄩ棬ID
-     * @return 缁撴灉 true 瀛樺湪 false 涓嶅瓨鍦�
-     */
-    @Override
-    public boolean checkDeptExistUser(Long deptId) {
-        return userMapper.exists(new LambdaQueryWrapper<SysUser>()
-            .eq(SysUser::getDeptId, deptId));
-    }
-
-    /**
-     * 鏍¢獙閮ㄩ棬鍚嶇О鏄惁鍞竴
-     *
-     * @param dept 閮ㄩ棬淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    public boolean checkDeptNameUnique(SysDeptBo dept) {
-        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysDept>()
-            .eq(SysDept::getDeptName, dept.getDeptName())
-            .eq(SysDept::getParentId, dept.getParentId())
-            .ne(ObjectUtil.isNotNull(dept.getDeptId()), SysDept::getDeptId, dept.getDeptId()));
-        return !exist;
-    }
-
-    /**
-     * 鏍¢獙閮ㄩ棬鏄惁鏈夋暟鎹潈闄�
-     *
-     * @param deptId 閮ㄩ棬id
-     */
-    @Override
-    public void checkDeptDataScope(Long deptId) {
-        if (ObjectUtil.isNull(deptId)) {
-            return;
-        }
-        if (LoginHelper.isSuperAdmin()) {
-            return;
-        }
-        SysDeptVo dept = baseMapper.selectDeptById(deptId);
-        if (ObjectUtil.isNull(dept)) {
-            throw new ServiceException("娌℃湁鏉冮檺璁块棶閮ㄩ棬鏁版嵁锛�");
-        }
-    }
-
-    /**
-     * 鏂板淇濆瓨閮ㄩ棬淇℃伅
-     *
-     * @param bo 閮ㄩ棬淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    public int insertDept(SysDeptBo bo) {
-        SysDept info = baseMapper.selectById(bo.getParentId());
-        // 濡傛灉鐖惰妭鐐逛笉涓烘甯哥姸鎬�,鍒欎笉鍏佽鏂板瀛愯妭鐐�
-        if (!UserConstants.DEPT_NORMAL.equals(info.getStatus())) {
-            throw new ServiceException("閮ㄩ棬鍋滅敤锛屼笉鍏佽鏂板");
-        }
-        SysDept dept = MapstructUtils.convert(bo, SysDept.class);
-        dept.setAncestors(info.getAncestors() + StringUtils.SEPARATOR + dept.getParentId());
-        return baseMapper.insert(dept);
-    }
-
-    /**
-     * 淇敼淇濆瓨閮ㄩ棬淇℃伅
-     *
-     * @param bo 閮ㄩ棬淇℃伅
-     * @return 缁撴灉
-     */
-    @CacheEvict(cacheNames = CacheNames.SYS_DEPT, key = "#bo.deptId")
-    @Override
-    public int updateDept(SysDeptBo bo) {
-        SysDept dept = MapstructUtils.convert(bo, SysDept.class);
-        SysDept oldDept = baseMapper.selectById(dept.getDeptId());
-        if (!oldDept.getParentId().equals(dept.getParentId())) {
-            // 濡傛灉鏄柊鐖堕儴闂� 鍒欐牎楠屾槸鍚﹀叿鏈夋柊鐖堕儴闂ㄦ潈闄� 閬垮厤瓒婃潈
-            this.checkDeptDataScope(dept.getParentId());
-            SysDept newParentDept = baseMapper.selectById(dept.getParentId());
-            if (ObjectUtil.isNotNull(newParentDept) && ObjectUtil.isNotNull(oldDept)) {
-                String newAncestors = newParentDept.getAncestors() + StringUtils.SEPARATOR + newParentDept.getDeptId();
-                String oldAncestors = oldDept.getAncestors();
-                dept.setAncestors(newAncestors);
-                updateDeptChildren(dept.getDeptId(), newAncestors, oldAncestors);
-            }
-        }
-        int result = baseMapper.updateById(dept);
-        if (UserConstants.DEPT_NORMAL.equals(dept.getStatus()) && StringUtils.isNotEmpty(dept.getAncestors())
-            && !StringUtils.equals(UserConstants.DEPT_NORMAL, dept.getAncestors())) {
-            // 濡傛灉璇ラ儴闂ㄦ槸鍚敤鐘舵�侊紝鍒欏惎鐢ㄨ閮ㄩ棬鐨勬墍鏈変笂绾ч儴闂�
-            updateParentDeptStatusNormal(dept);
-        }
-        return result;
-    }
-
-    /**
-     * 淇敼璇ラ儴闂ㄧ殑鐖剁骇閮ㄩ棬鐘舵��
-     *
-     * @param dept 褰撳墠閮ㄩ棬
-     */
-    private void updateParentDeptStatusNormal(SysDept dept) {
-        String ancestors = dept.getAncestors();
-        Long[] deptIds = Convert.toLongArray(ancestors);
-        baseMapper.update(null, new LambdaUpdateWrapper<SysDept>()
-            .set(SysDept::getStatus, UserConstants.DEPT_NORMAL)
-            .in(SysDept::getDeptId, Arrays.asList(deptIds)));
-    }
-
-    /**
-     * 淇敼瀛愬厓绱犲叧绯�
-     *
-     * @param deptId       琚慨鏀圭殑閮ㄩ棬ID
-     * @param newAncestors 鏂扮殑鐖禝D闆嗗悎
-     * @param oldAncestors 鏃х殑鐖禝D闆嗗悎
-     */
-    private void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors) {
-        List<SysDept> children = baseMapper.selectList(new LambdaQueryWrapper<SysDept>()
-            .apply(DataBaseHelper.findInSet(deptId, "ancestors")));
-        List<SysDept> list = new ArrayList<>();
-        for (SysDept child : children) {
-            SysDept dept = new SysDept();
-            dept.setDeptId(child.getDeptId());
-            dept.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
-            list.add(dept);
-        }
-        if (CollUtil.isNotEmpty(list)) {
-            if (baseMapper.updateBatchById(list)) {
-                list.forEach(dept -> CacheUtils.evict(CacheNames.SYS_DEPT, dept.getDeptId()));
-            }
-        }
-    }
-
-    /**
-     * 鍒犻櫎閮ㄩ棬绠$悊淇℃伅
-     *
-     * @param deptId 閮ㄩ棬ID
-     * @return 缁撴灉
-     */
-    @CacheEvict(cacheNames = CacheNames.SYS_DEPT, key = "#deptId")
-    @Override
-    public int deleteDeptById(Long deptId) {
-        return baseMapper.deleteById(deptId);
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java
deleted file mode 100644
index 4197126..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java
+++ /dev/null
@@ -1,139 +0,0 @@
-package com.ruoyi.system.service.impl;
-
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.core.constant.CacheNames;
-import com.ruoyi.common.core.utils.MapstructUtils;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.system.domain.SysDictData;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.redis.utils.CacheUtils;
-import com.ruoyi.system.domain.bo.SysDictDataBo;
-import com.ruoyi.system.domain.vo.SysDictDataVo;
-import com.ruoyi.system.mapper.SysDictDataMapper;
-import com.ruoyi.system.service.ISysDictDataService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.cache.annotation.CachePut;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-
-/**
- * 瀛楀吀 涓氬姟灞傚鐞�
- *
- * @author Lion Li
- */
-@RequiredArgsConstructor
-@Service
-public class SysDictDataServiceImpl implements ISysDictDataService {
-
-    private final SysDictDataMapper baseMapper;
-
-    @Override
-    public TableDataInfo<SysDictDataVo> selectPageDictDataList(SysDictDataBo dictData, PageQuery pageQuery) {
-        LambdaQueryWrapper<SysDictData> lqw = buildQueryWrapper(dictData);
-        Page<SysDictDataVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw);
-        return TableDataInfo.build(page);
-    }
-
-    /**
-     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瀛楀吀鏁版嵁
-     *
-     * @param dictData 瀛楀吀鏁版嵁淇℃伅
-     * @return 瀛楀吀鏁版嵁闆嗗悎淇℃伅
-     */
-    @Override
-    public List<SysDictDataVo> selectDictDataList(SysDictDataBo dictData) {
-        LambdaQueryWrapper<SysDictData> lqw = buildQueryWrapper(dictData);
-        return baseMapper.selectVoList(lqw);
-    }
-
-    private LambdaQueryWrapper<SysDictData> buildQueryWrapper(SysDictDataBo bo) {
-        LambdaQueryWrapper<SysDictData> lqw = Wrappers.lambdaQuery();
-        lqw.eq(bo.getDictSort() != null, SysDictData::getDictSort, bo.getDictSort());
-        lqw.like(StringUtils.isNotBlank(bo.getDictLabel()), SysDictData::getDictLabel, bo.getDictLabel());
-        lqw.eq(StringUtils.isNotBlank(bo.getDictType()), SysDictData::getDictType, bo.getDictType());
-        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysDictData::getStatus, bo.getStatus());
-        lqw.orderByAsc(SysDictData::getDictSort);
-        return lqw;
-    }
-
-    /**
-     * 鏍规嵁瀛楀吀绫诲瀷鍜屽瓧鍏搁敭鍊兼煡璇㈠瓧鍏告暟鎹俊鎭�
-     *
-     * @param dictType  瀛楀吀绫诲瀷
-     * @param dictValue 瀛楀吀閿��
-     * @return 瀛楀吀鏍囩
-     */
-    @Override
-    public String selectDictLabel(String dictType, String dictValue) {
-        return baseMapper.selectOne(new LambdaQueryWrapper<SysDictData>()
-                .select(SysDictData::getDictLabel)
-                .eq(SysDictData::getDictType, dictType)
-                .eq(SysDictData::getDictValue, dictValue))
-            .getDictLabel();
-    }
-
-    /**
-     * 鏍规嵁瀛楀吀鏁版嵁ID鏌ヨ淇℃伅
-     *
-     * @param dictCode 瀛楀吀鏁版嵁ID
-     * @return 瀛楀吀鏁版嵁
-     */
-    @Override
-    public SysDictDataVo selectDictDataById(Long dictCode) {
-        return baseMapper.selectVoById(dictCode);
-    }
-
-    /**
-     * 鎵归噺鍒犻櫎瀛楀吀鏁版嵁淇℃伅
-     *
-     * @param dictCodes 闇�瑕佸垹闄ょ殑瀛楀吀鏁版嵁ID
-     */
-    @Override
-    public void deleteDictDataByIds(Long[] dictCodes) {
-        for (Long dictCode : dictCodes) {
-            SysDictData data = baseMapper.selectById(dictCode);
-            baseMapper.deleteById(dictCode);
-            CacheUtils.evict(CacheNames.SYS_DICT, data.getDictType());
-        }
-    }
-
-    /**
-     * 鏂板淇濆瓨瀛楀吀鏁版嵁淇℃伅
-     *
-     * @param bo 瀛楀吀鏁版嵁淇℃伅
-     * @return 缁撴灉
-     */
-    @CachePut(cacheNames = CacheNames.SYS_DICT, key = "#bo.dictType")
-    @Override
-    public List<SysDictDataVo> insertDictData(SysDictDataBo bo) {
-        SysDictData data = MapstructUtils.convert(bo, SysDictData.class);
-        int row = baseMapper.insert(data);
-        if (row > 0) {
-            return baseMapper.selectDictDataByType(data.getDictType());
-        }
-        throw new ServiceException("鎿嶄綔澶辫触");
-    }
-
-    /**
-     * 淇敼淇濆瓨瀛楀吀鏁版嵁淇℃伅
-     *
-     * @param bo 瀛楀吀鏁版嵁淇℃伅
-     * @return 缁撴灉
-     */
-    @CachePut(cacheNames = CacheNames.SYS_DICT, key = "#bo.dictType")
-    @Override
-    public List<SysDictDataVo> updateDictData(SysDictDataBo bo) {
-        SysDictData data = MapstructUtils.convert(bo, SysDictData.class);
-        int row = baseMapper.updateById(data);
-        if (row > 0) {
-            return baseMapper.selectDictDataByType(data.getDictType());
-        }
-        throw new ServiceException("鎿嶄綔澶辫触");
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java
deleted file mode 100644
index c0f68c3..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java
+++ /dev/null
@@ -1,268 +0,0 @@
-package com.ruoyi.system.service.impl;
-
-import cn.dev33.satoken.context.SaHolder;
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.ObjectUtil;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.core.constant.CacheConstants;
-import com.ruoyi.common.core.constant.CacheNames;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.service.DictService;
-import com.ruoyi.common.core.utils.MapstructUtils;
-import com.ruoyi.common.core.utils.SpringUtils;
-import com.ruoyi.common.core.utils.StreamUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.redis.utils.CacheUtils;
-import com.ruoyi.system.domain.SysDictData;
-import com.ruoyi.system.domain.SysDictType;
-import com.ruoyi.system.domain.bo.SysDictTypeBo;
-import com.ruoyi.system.domain.vo.SysDictDataVo;
-import com.ruoyi.system.domain.vo.SysDictTypeVo;
-import com.ruoyi.system.mapper.SysDictDataMapper;
-import com.ruoyi.system.mapper.SysDictTypeMapper;
-import com.ruoyi.system.service.ISysDictTypeService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.cache.annotation.CachePut;
-import org.springframework.cache.annotation.Cacheable;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-/**
- * 瀛楀吀 涓氬姟灞傚鐞�
- *
- * @author Lion Li
- */
-@RequiredArgsConstructor
-@Service
-public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService {
-
-    private final SysDictTypeMapper baseMapper;
-    private final SysDictDataMapper dictDataMapper;
-
-    @Override
-    public TableDataInfo<SysDictTypeVo> selectPageDictTypeList(SysDictTypeBo dictType, PageQuery pageQuery) {
-        LambdaQueryWrapper<SysDictType> lqw = buildQueryWrapper(dictType);
-        Page<SysDictTypeVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw);
-        return TableDataInfo.build(page);
-    }
-
-    /**
-     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瀛楀吀绫诲瀷
-     *
-     * @param dictType 瀛楀吀绫诲瀷淇℃伅
-     * @return 瀛楀吀绫诲瀷闆嗗悎淇℃伅
-     */
-    @Override
-    public List<SysDictTypeVo> selectDictTypeList(SysDictTypeBo dictType) {
-        LambdaQueryWrapper<SysDictType> lqw = buildQueryWrapper(dictType);
-        return baseMapper.selectVoList(lqw);
-    }
-
-    private LambdaQueryWrapper<SysDictType> buildQueryWrapper(SysDictTypeBo bo) {
-        Map<String, Object> params = bo.getParams();
-        LambdaQueryWrapper<SysDictType> lqw = Wrappers.lambdaQuery();
-        lqw.like(StringUtils.isNotBlank(bo.getDictName()), SysDictType::getDictName, bo.getDictName());
-        lqw.like(StringUtils.isNotBlank(bo.getDictType()), SysDictType::getDictType, bo.getDictType());
-        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysDictType::getStatus, bo.getStatus());
-        lqw.between(params.get("beginTime") != null && params.get("endTime") != null,
-            SysDictType::getCreateTime, params.get("beginTime"), params.get("endTime"));
-        return lqw;
-    }
-
-    /**
-     * 鏍规嵁鎵�鏈夊瓧鍏哥被鍨�
-     *
-     * @return 瀛楀吀绫诲瀷闆嗗悎淇℃伅
-     */
-    @Override
-    public List<SysDictTypeVo> selectDictTypeAll() {
-        return baseMapper.selectVoList();
-    }
-
-    /**
-     * 鏍规嵁瀛楀吀绫诲瀷鏌ヨ瀛楀吀鏁版嵁
-     *
-     * @param dictType 瀛楀吀绫诲瀷
-     * @return 瀛楀吀鏁版嵁闆嗗悎淇℃伅
-     */
-    @Cacheable(cacheNames = CacheNames.SYS_DICT, key = "#dictType")
-    @Override
-    public List<SysDictDataVo> selectDictDataByType(String dictType) {
-        List<SysDictDataVo> dictDatas = dictDataMapper.selectDictDataByType(dictType);
-        if (CollUtil.isNotEmpty(dictDatas)) {
-            return dictDatas;
-        }
-        return null;
-    }
-
-    /**
-     * 鏍规嵁瀛楀吀绫诲瀷ID鏌ヨ淇℃伅
-     *
-     * @param dictId 瀛楀吀绫诲瀷ID
-     * @return 瀛楀吀绫诲瀷
-     */
-    @Override
-    public SysDictTypeVo selectDictTypeById(Long dictId) {
-        return baseMapper.selectVoById(dictId);
-    }
-
-    /**
-     * 鏍规嵁瀛楀吀绫诲瀷鏌ヨ淇℃伅
-     *
-     * @param dictType 瀛楀吀绫诲瀷
-     * @return 瀛楀吀绫诲瀷
-     */
-    @Cacheable(cacheNames = CacheNames.SYS_DICT, key = "#dictType")
-    @Override
-    public SysDictTypeVo selectDictTypeByType(String dictType) {
-        return baseMapper.selectVoById(new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getDictType, dictType));
-    }
-
-    /**
-     * 鎵归噺鍒犻櫎瀛楀吀绫诲瀷淇℃伅
-     *
-     * @param dictIds 闇�瑕佸垹闄ょ殑瀛楀吀ID
-     */
-    @Override
-    public void deleteDictTypeByIds(Long[] dictIds) {
-        for (Long dictId : dictIds) {
-            SysDictType dictType = baseMapper.selectById(dictId);
-            if (dictDataMapper.exists(new LambdaQueryWrapper<SysDictData>()
-                .eq(SysDictData::getDictType, dictType.getDictType()))) {
-                throw new ServiceException(String.format("%1$s宸插垎閰�,涓嶈兘鍒犻櫎", dictType.getDictName()));
-            }
-            CacheUtils.evict(CacheNames.SYS_DICT, dictType.getDictType());
-        }
-        baseMapper.deleteBatchIds(Arrays.asList(dictIds));
-    }
-
-    /**
-     * 閲嶇疆瀛楀吀缂撳瓨鏁版嵁
-     */
-    @Override
-    public void resetDictCache() {
-        CacheUtils.clear(CacheNames.SYS_DICT);
-    }
-
-    /**
-     * 鏂板淇濆瓨瀛楀吀绫诲瀷淇℃伅
-     *
-     * @param bo 瀛楀吀绫诲瀷淇℃伅
-     * @return 缁撴灉
-     */
-    @CachePut(cacheNames = CacheNames.SYS_DICT, key = "#bo.dictType")
-    @Override
-    public List<SysDictTypeVo> insertDictType(SysDictTypeBo bo) {
-        SysDictType dict = MapstructUtils.convert(bo, SysDictType.class);
-        int row = baseMapper.insert(dict);
-        if (row > 0) {
-            return new ArrayList<>();
-        }
-        throw new ServiceException("鎿嶄綔澶辫触");
-    }
-
-    /**
-     * 淇敼淇濆瓨瀛楀吀绫诲瀷淇℃伅
-     *
-     * @param bo 瀛楀吀绫诲瀷淇℃伅
-     * @return 缁撴灉
-     */
-    @CachePut(cacheNames = CacheNames.SYS_DICT, key = "#bo.dictType")
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public List<SysDictDataVo> updateDictType(SysDictTypeBo bo) {
-        SysDictType dict = MapstructUtils.convert(bo, SysDictType.class);
-        SysDictType oldDict = baseMapper.selectById(dict.getDictId());
-        dictDataMapper.update(null, new LambdaUpdateWrapper<SysDictData>()
-            .set(SysDictData::getDictType, dict.getDictType())
-            .eq(SysDictData::getDictType, oldDict.getDictType()));
-        int row = baseMapper.updateById(dict);
-        if (row > 0) {
-            CacheUtils.evict(CacheNames.SYS_DICT, oldDict.getDictType());
-            return dictDataMapper.selectDictDataByType(dict.getDictType());
-        }
-        throw new ServiceException("鎿嶄綔澶辫触");
-    }
-
-    /**
-     * 鏍¢獙瀛楀吀绫诲瀷绉版槸鍚﹀敮涓�
-     *
-     * @param dictType 瀛楀吀绫诲瀷
-     * @return 缁撴灉
-     */
-    @Override
-    public boolean checkDictTypeUnique(SysDictTypeBo dictType) {
-        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysDictType>()
-            .eq(SysDictType::getDictType, dictType.getDictType())
-            .ne(ObjectUtil.isNotNull(dictType.getDictId()), SysDictType::getDictId, dictType.getDictId()));
-        return !exist;
-    }
-
-    /**
-     * 鏍规嵁瀛楀吀绫诲瀷鍜屽瓧鍏稿�艰幏鍙栧瓧鍏告爣绛�
-     *
-     * @param dictType  瀛楀吀绫诲瀷
-     * @param dictValue 瀛楀吀鍊�
-     * @param separator 鍒嗛殧绗�
-     * @return 瀛楀吀鏍囩
-     */
-    @SuppressWarnings("unchecked cast")
-    @Override
-    public String getDictLabel(String dictType, String dictValue, String separator) {
-        // 浼樺厛浠庢湰鍦扮紦瀛樿幏鍙�
-        List<SysDictDataVo> datas = (List<SysDictDataVo>) SaHolder.getStorage().get(CacheConstants.SYS_DICT_KEY + dictType);
-        if (ObjectUtil.isNull(datas)) {
-            datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType);
-            SaHolder.getStorage().set(CacheConstants.SYS_DICT_KEY + dictType, datas);
-        }
-
-        Map<String, String> map = StreamUtils.toMap(datas, SysDictDataVo::getDictValue, SysDictDataVo::getDictLabel);
-        if (StringUtils.containsAny(dictValue, separator)) {
-            return Arrays.stream(dictValue.split(separator))
-                .map(v -> map.getOrDefault(v, StringUtils.EMPTY))
-                .collect(Collectors.joining(separator));
-        } else {
-            return map.getOrDefault(dictValue, StringUtils.EMPTY);
-        }
-    }
-
-    /**
-     * 鏍规嵁瀛楀吀绫诲瀷鍜屽瓧鍏告爣绛捐幏鍙栧瓧鍏稿��
-     *
-     * @param dictType  瀛楀吀绫诲瀷
-     * @param dictLabel 瀛楀吀鏍囩
-     * @param separator 鍒嗛殧绗�
-     * @return 瀛楀吀鍊�
-     */
-    @SuppressWarnings("unchecked cast")
-    @Override
-    public String getDictValue(String dictType, String dictLabel, String separator) {
-        // 浼樺厛浠庢湰鍦扮紦瀛樿幏鍙�
-        List<SysDictDataVo> datas = (List<SysDictDataVo>) SaHolder.getStorage().get(CacheConstants.SYS_DICT_KEY + dictType);
-        if (ObjectUtil.isNull(datas)) {
-            datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType);
-            SaHolder.getStorage().set(CacheConstants.SYS_DICT_KEY + dictType, datas);
-        }
-
-        Map<String, String> map = StreamUtils.toMap(datas, SysDictDataVo::getDictLabel, SysDictDataVo::getDictValue);
-        if (StringUtils.containsAny(dictLabel, separator)) {
-            return Arrays.stream(dictLabel.split(separator))
-                .map(l -> map.getOrDefault(l, StringUtils.EMPTY))
-                .collect(Collectors.joining(separator));
-        } else {
-            return map.getOrDefault(dictLabel, StringUtils.EMPTY);
-        }
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java
deleted file mode 100644
index 470d383..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java
+++ /dev/null
@@ -1,160 +0,0 @@
-package com.ruoyi.system.service.impl;
-
-import cn.hutool.http.useragent.UserAgent;
-import cn.hutool.http.useragent.UserAgentUtil;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.core.constant.Constants;
-import com.ruoyi.common.core.utils.MapstructUtils;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.log.event.LogininforEvent;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.core.utils.ServletUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.core.utils.ip.AddressUtils;
-import com.ruoyi.system.domain.SysLogininfor;
-import com.ruoyi.system.domain.bo.SysLogininforBo;
-import com.ruoyi.system.domain.vo.SysLogininforVo;
-import com.ruoyi.system.mapper.SysLogininforMapper;
-import com.ruoyi.system.service.ISysLogininforService;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.context.event.EventListener;
-import org.springframework.scheduling.annotation.Async;
-import org.springframework.stereotype.Service;
-
-import jakarta.servlet.http.HttpServletRequest;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 绯荤粺璁块棶鏃ュ織鎯呭喌淇℃伅 鏈嶅姟灞傚鐞�
- *
- * @author Lion Li
- */
-@RequiredArgsConstructor
-@Slf4j
-@Service
-public class SysLogininforServiceImpl implements ISysLogininforService {
-
-    private final SysLogininforMapper baseMapper;
-
-    /**
-     * 璁板綍鐧诲綍淇℃伅
-     *
-     * @param logininforEvent 鐧诲綍浜嬩欢
-     */
-    @Async
-    @EventListener
-    public void recordLogininfor(LogininforEvent logininforEvent) {
-        HttpServletRequest request = logininforEvent.getRequest();
-        final UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
-        final String ip = ServletUtils.getClientIP(request);
-
-        String address = AddressUtils.getRealAddressByIP(ip);
-        StringBuilder s = new StringBuilder();
-        s.append(getBlock(ip));
-        s.append(address);
-        s.append(getBlock(logininforEvent.getUsername()));
-        s.append(getBlock(logininforEvent.getStatus()));
-        s.append(getBlock(logininforEvent.getMessage()));
-        // 鎵撳嵃淇℃伅鍒版棩蹇�
-        log.info(s.toString(), logininforEvent.getArgs());
-        // 鑾峰彇瀹㈡埛绔搷浣滅郴缁�
-        String os = userAgent.getOs().getName();
-        // 鑾峰彇瀹㈡埛绔祻瑙堝櫒
-        String browser = userAgent.getBrowser().getName();
-        // 灏佽瀵硅薄
-        SysLogininforBo logininfor = new SysLogininforBo();
-        logininfor.setTenantId(logininforEvent.getTenantId());
-        logininfor.setUserName(logininforEvent.getUsername());
-        logininfor.setIpaddr(ip);
-        logininfor.setLoginLocation(address);
-        logininfor.setBrowser(browser);
-        logininfor.setOs(os);
-        logininfor.setMsg(logininforEvent.getMessage());
-        // 鏃ュ織鐘舵��
-        if (StringUtils.equalsAny(logininforEvent.getStatus(), Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) {
-            logininfor.setStatus(Constants.SUCCESS);
-        } else if (Constants.LOGIN_FAIL.equals(logininforEvent.getStatus())) {
-            logininfor.setStatus(Constants.FAIL);
-        }
-        // 鎻掑叆鏁版嵁
-        insertLogininfor(logininfor);
-    }
-
-    private String getBlock(Object msg) {
-        if (msg == null) {
-            msg = "";
-        }
-        return "[" + msg.toString() + "]";
-    }
-
-    @Override
-    public TableDataInfo<SysLogininforVo> selectPageLogininforList(SysLogininforBo logininfor, PageQuery pageQuery) {
-        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())
-            .between(params.get("beginTime") != null && params.get("endTime") != null,
-                SysLogininfor::getLoginTime, params.get("beginTime"), params.get("endTime"));
-        if (StringUtils.isBlank(pageQuery.getOrderByColumn())) {
-            pageQuery.setOrderByColumn("info_id");
-            pageQuery.setIsAsc("desc");
-        }
-        Page<SysLogininforVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw);
-        return TableDataInfo.build(page);
-    }
-
-    /**
-     * 鏂板绯荤粺鐧诲綍鏃ュ織
-     *
-     * @param bo 璁块棶鏃ュ織瀵硅薄
-     */
-    @Override
-    public void insertLogininfor(SysLogininforBo bo) {
-        SysLogininfor logininfor = MapstructUtils.convert(bo, SysLogininfor.class);
-        logininfor.setLoginTime(new Date());
-        baseMapper.insert(logininfor);
-    }
-
-    /**
-     * 鏌ヨ绯荤粺鐧诲綍鏃ュ織闆嗗悎
-     *
-     * @param logininfor 璁块棶鏃ュ織瀵硅薄
-     * @return 鐧诲綍璁板綍闆嗗悎
-     */
-    @Override
-    public List<SysLogininforVo> selectLogininforList(SysLogininforBo logininfor) {
-        Map<String, Object> params = logininfor.getParams();
-        return baseMapper.selectVoList(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())
-            .between(params.get("beginTime") != null && params.get("endTime") != null,
-                SysLogininfor::getLoginTime, params.get("beginTime"), params.get("endTime"))
-            .orderByDesc(SysLogininfor::getInfoId));
-    }
-
-    /**
-     * 鎵归噺鍒犻櫎绯荤粺鐧诲綍鏃ュ織
-     *
-     * @param infoIds 闇�瑕佸垹闄ょ殑鐧诲綍鏃ュ織ID
-     * @return 缁撴灉
-     */
-    @Override
-    public int deleteLogininforByIds(Long[] infoIds) {
-        return baseMapper.deleteBatchIds(Arrays.asList(infoIds));
-    }
-
-    /**
-     * 娓呯┖绯荤粺鐧诲綍鏃ュ織
-     */
-    @Override
-    public void cleanLogininfor() {
-        baseMapper.delete(new LambdaQueryWrapper<>());
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java
deleted file mode 100644
index dc7efca..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java
+++ /dev/null
@@ -1,365 +0,0 @@
-package com.ruoyi.system.service.impl;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.convert.Convert;
-import cn.hutool.core.lang.tree.Tree;
-import cn.hutool.core.util.ObjectUtil;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.ruoyi.common.core.constant.UserConstants;
-import com.ruoyi.common.core.utils.MapstructUtils;
-import com.ruoyi.common.core.utils.StreamUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.core.utils.TreeBuildUtils;
-import com.ruoyi.common.satoken.utils.LoginHelper;
-import com.ruoyi.system.domain.SysMenu;
-import com.ruoyi.system.domain.SysRole;
-import com.ruoyi.system.domain.SysRoleMenu;
-import com.ruoyi.system.domain.SysTenantPackage;
-import com.ruoyi.system.domain.bo.SysMenuBo;
-import com.ruoyi.system.domain.vo.MetaVo;
-import com.ruoyi.system.domain.vo.RouterVo;
-import com.ruoyi.system.domain.vo.SysMenuVo;
-import com.ruoyi.system.mapper.SysMenuMapper;
-import com.ruoyi.system.mapper.SysRoleMapper;
-import com.ruoyi.system.mapper.SysRoleMenuMapper;
-import com.ruoyi.system.mapper.SysTenantPackageMapper;
-import com.ruoyi.system.service.ISysMenuService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Service;
-
-import java.util.*;
-
-/**
- * 鑿滃崟 涓氬姟灞傚鐞�
- *
- * @author Lion Li
- */
-@RequiredArgsConstructor
-@Service
-public class SysMenuServiceImpl implements ISysMenuService {
-
-    private final SysMenuMapper baseMapper;
-    private final SysRoleMapper roleMapper;
-    private final SysRoleMenuMapper roleMenuMapper;
-    private final SysTenantPackageMapper tenantPackageMapper;
-
-    /**
-     * 鏍规嵁鐢ㄦ埛鏌ヨ绯荤粺鑿滃崟鍒楄〃
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 鑿滃崟鍒楄〃
-     */
-    @Override
-    public List<SysMenuVo> selectMenuList(Long userId) {
-        return selectMenuList(new SysMenuBo(), userId);
-    }
-
-    /**
-     * 鏌ヨ绯荤粺鑿滃崟鍒楄〃
-     *
-     * @param menu 鑿滃崟淇℃伅
-     * @return 鑿滃崟鍒楄〃
-     */
-    @Override
-    public List<SysMenuVo> selectMenuList(SysMenuBo menu, Long userId) {
-        List<SysMenuVo> menuList;
-        // 绠$悊鍛樻樉绀烘墍鏈夎彍鍗曚俊鎭�
-        if (LoginHelper.isSuperAdmin(userId)) {
-            menuList = baseMapper.selectVoList(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));
-        } else {
-            QueryWrapper<SysMenu> wrapper = Wrappers.query();
-            wrapper.eq("sur.user_id", userId)
-                .like(StringUtils.isNotBlank(menu.getMenuName()), "m.menu_name", menu.getMenuName())
-                .eq(StringUtils.isNotBlank(menu.getVisible()), "m.visible", menu.getVisible())
-                .eq(StringUtils.isNotBlank(menu.getStatus()), "m.status", menu.getStatus())
-                .orderByAsc("m.parent_id")
-                .orderByAsc("m.order_num");
-            List<SysMenu> list = baseMapper.selectMenuListByUserId(wrapper);
-            menuList = MapstructUtils.convert(list, SysMenuVo.class);
-        }
-        return menuList;
-    }
-
-    /**
-     * 鏍规嵁鐢ㄦ埛ID鏌ヨ鏉冮檺
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 鏉冮檺鍒楄〃
-     */
-    @Override
-    public Set<String> selectMenuPermsByUserId(Long userId) {
-        List<String> perms = baseMapper.selectMenuPermsByUserId(userId);
-        Set<String> permsSet = new HashSet<>();
-        for (String perm : perms) {
-            if (StringUtils.isNotEmpty(perm)) {
-                permsSet.addAll(StringUtils.splitList(perm.trim()));
-            }
-        }
-        return permsSet;
-    }
-
-    /**
-     * 鏍规嵁瑙掕壊ID鏌ヨ鏉冮檺
-     *
-     * @param roleId 瑙掕壊ID
-     * @return 鏉冮檺鍒楄〃
-     */
-    @Override
-    public Set<String> selectMenuPermsByRoleId(Long roleId) {
-        List<String> perms = baseMapper.selectMenuPermsByRoleId(roleId);
-        Set<String> permsSet = new HashSet<>();
-        for (String perm : perms) {
-            if (StringUtils.isNotEmpty(perm)) {
-                permsSet.addAll(StringUtils.splitList(perm.trim()));
-            }
-        }
-        return permsSet;
-    }
-
-    /**
-     * 鏍规嵁鐢ㄦ埛ID鏌ヨ鑿滃崟
-     *
-     * @param userId 鐢ㄦ埛鍚嶇О
-     * @return 鑿滃崟鍒楄〃
-     */
-    @Override
-    public List<SysMenu> selectMenuTreeByUserId(Long userId) {
-        List<SysMenu> menus;
-        if (LoginHelper.isSuperAdmin(userId)) {
-            menus = baseMapper.selectMenuTreeAll();
-        } else {
-            menus = baseMapper.selectMenuTreeByUserId(userId);
-        }
-        return getChildPerms(menus, 0);
-    }
-
-    /**
-     * 鏍规嵁瑙掕壊ID鏌ヨ鑿滃崟鏍戜俊鎭�
-     *
-     * @param roleId 瑙掕壊ID
-     * @return 閫変腑鑿滃崟鍒楄〃
-     */
-    @Override
-    public List<Long> selectMenuListByRoleId(Long roleId) {
-        SysRole role = roleMapper.selectById(roleId);
-        return baseMapper.selectMenuListByRoleId(roleId, role.getMenuCheckStrictly());
-    }
-
-    /**
-     * 鏍规嵁绉熸埛濂楅ID鏌ヨ鑿滃崟鏍戜俊鎭�
-     *
-     * @param packageId 绉熸埛濂楅ID
-     * @return 閫変腑鑿滃崟鍒楄〃
-     */
-    @Override
-    public List<Long> selectMenuListByPackageId(Long packageId) {
-        SysTenantPackage tenantPackage = tenantPackageMapper.selectById(packageId);
-        List<Long> menuIds = StringUtils.splitTo(tenantPackage.getMenuIds(), Convert::toLong);
-        if (CollUtil.isEmpty(menuIds)) {
-            return List.of();
-        }
-        List<Long> parentIds = null;
-        if (tenantPackage.getMenuCheckStrictly()) {
-            parentIds = baseMapper.selectObjs(new LambdaQueryWrapper<SysMenu>()
-                .select(SysMenu::getParentId)
-                .in(SysMenu::getMenuId, menuIds), Convert::toLong);
-        }
-        return baseMapper.selectObjs(new LambdaQueryWrapper<SysMenu>()
-            .in(SysMenu::getMenuId, menuIds)
-            .notIn(CollUtil.isNotEmpty(parentIds), SysMenu::getMenuId, parentIds), Convert::toLong);
-    }
-
-    /**
-     * 鏋勫缓鍓嶇璺敱鎵�闇�瑕佺殑鑿滃崟
-     *
-     * @param menus 鑿滃崟鍒楄〃
-     * @return 璺敱鍒楄〃
-     */
-    @Override
-    public List<RouterVo> buildMenus(List<SysMenu> menus) {
-        List<RouterVo> routers = new LinkedList<>();
-        for (SysMenu menu : menus) {
-            RouterVo router = new RouterVo();
-            router.setHidden("1".equals(menu.getVisible()));
-            router.setName(menu.getRouteName());
-            router.setPath(menu.getRouterPath());
-            router.setComponent(menu.getComponentInfo());
-            router.setQuery(menu.getQueryParam());
-            router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath()));
-            List<SysMenu> cMenus = menu.getChildren();
-            if (CollUtil.isNotEmpty(cMenus) && UserConstants.TYPE_DIR.equals(menu.getMenuType())) {
-                router.setAlwaysShow(true);
-                router.setRedirect("noRedirect");
-                router.setChildren(buildMenus(cMenus));
-            } else if (menu.isMenuFrame()) {
-                router.setMeta(null);
-                List<RouterVo> childrenList = new ArrayList<>();
-                RouterVo children = new RouterVo();
-                children.setPath(menu.getPath());
-                children.setComponent(menu.getComponentInfo());
-                children.setName(StringUtils.capitalize(menu.getPath()));
-                children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath()));
-                children.setQuery(menu.getQueryParam());
-                childrenList.add(children);
-                router.setChildren(childrenList);
-            } else if (menu.getParentId().intValue() == 0 && menu.isInnerLink()) {
-                router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon()));
-                router.setPath("/");
-                List<RouterVo> childrenList = new ArrayList<>();
-                RouterVo children = new RouterVo();
-                String routerPath = SysMenu.innerLinkReplaceEach(menu.getPath());
-                children.setPath(routerPath);
-                children.setComponent(UserConstants.INNER_LINK);
-                children.setName(StringUtils.capitalize(routerPath));
-                children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath()));
-                childrenList.add(children);
-                router.setChildren(childrenList);
-            }
-            routers.add(router);
-        }
-        return routers;
-    }
-
-    /**
-     * 鏋勫缓鍓嶇鎵�闇�瑕佷笅鎷夋爲缁撴瀯
-     *
-     * @param menus 鑿滃崟鍒楄〃
-     * @return 涓嬫媺鏍戠粨鏋勫垪琛�
-     */
-    @Override
-    public List<Tree<Long>> buildMenuTreeSelect(List<SysMenuVo> menus) {
-        if (CollUtil.isEmpty(menus)) {
-            return CollUtil.newArrayList();
-        }
-        return TreeBuildUtils.build(menus, (menu, tree) ->
-            tree.setId(menu.getMenuId())
-                .setParentId(menu.getParentId())
-                .setName(menu.getMenuName())
-                .setWeight(menu.getOrderNum()));
-    }
-
-    /**
-     * 鏍规嵁鑿滃崟ID鏌ヨ淇℃伅
-     *
-     * @param menuId 鑿滃崟ID
-     * @return 鑿滃崟淇℃伅
-     */
-    @Override
-    public SysMenuVo selectMenuById(Long menuId) {
-        return baseMapper.selectVoById(menuId);
-    }
-
-    /**
-     * 鏄惁瀛樺湪鑿滃崟瀛愯妭鐐�
-     *
-     * @param menuId 鑿滃崟ID
-     * @return 缁撴灉
-     */
-    @Override
-    public boolean hasChildByMenuId(Long menuId) {
-        return baseMapper.exists(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getParentId, menuId));
-    }
-
-    /**
-     * 鏌ヨ鑿滃崟浣跨敤鏁伴噺
-     *
-     * @param menuId 鑿滃崟ID
-     * @return 缁撴灉
-     */
-    @Override
-    public boolean checkMenuExistRole(Long menuId) {
-        return roleMenuMapper.exists(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getMenuId, menuId));
-    }
-
-    /**
-     * 鏂板淇濆瓨鑿滃崟淇℃伅
-     *
-     * @param bo 鑿滃崟淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    public int insertMenu(SysMenuBo bo) {
-        SysMenu menu = MapstructUtils.convert(bo, SysMenu.class);
-        return baseMapper.insert(menu);
-    }
-
-    /**
-     * 淇敼淇濆瓨鑿滃崟淇℃伅
-     *
-     * @param bo 鑿滃崟淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    public int updateMenu(SysMenuBo bo) {
-        SysMenu menu = MapstructUtils.convert(bo, SysMenu.class);
-        return baseMapper.updateById(menu);
-    }
-
-    /**
-     * 鍒犻櫎鑿滃崟绠$悊淇℃伅
-     *
-     * @param menuId 鑿滃崟ID
-     * @return 缁撴灉
-     */
-    @Override
-    public int deleteMenuById(Long menuId) {
-        return baseMapper.deleteById(menuId);
-    }
-
-    /**
-     * 鏍¢獙鑿滃崟鍚嶇О鏄惁鍞竴
-     *
-     * @param menu 鑿滃崟淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    public boolean checkMenuNameUnique(SysMenuBo menu) {
-        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysMenu>()
-            .eq(SysMenu::getMenuName, menu.getMenuName())
-            .eq(SysMenu::getParentId, menu.getParentId())
-            .ne(ObjectUtil.isNotNull(menu.getMenuId()), SysMenu::getMenuId, menu.getMenuId()));
-        return !exist;
-    }
-
-    /**
-     * 鏍规嵁鐖惰妭鐐圭殑ID鑾峰彇鎵�鏈夊瓙鑺傜偣
-     *
-     * @param list     鍒嗙被琛�
-     * @param parentId 浼犲叆鐨勭埗鑺傜偣ID
-     * @return String
-     */
-    private List<SysMenu> getChildPerms(List<SysMenu> list, int parentId) {
-        List<SysMenu> returnList = new ArrayList<>();
-        for (SysMenu t : list) {
-            // 涓�銆佹牴鎹紶鍏ョ殑鏌愪釜鐖惰妭鐐笽D,閬嶅巻璇ョ埗鑺傜偣鐨勬墍鏈夊瓙鑺傜偣
-            if (t.getParentId() == parentId) {
-                recursionFn(list, t);
-                returnList.add(t);
-            }
-        }
-        return returnList;
-    }
-
-    /**
-     * 閫掑綊鍒楄〃
-     */
-    private void recursionFn(List<SysMenu> list, SysMenu t) {
-        // 寰楀埌瀛愯妭鐐瑰垪琛�
-        List<SysMenu> childList = StreamUtils.filter(list, n -> n.getParentId().equals(t.getMenuId()));
-        t.setChildren(childList);
-        for (SysMenu tChild : childList) {
-            // 鍒ゆ柇鏄惁鏈夊瓙鑺傜偣
-            if (list.stream().anyMatch(n -> n.getParentId().equals(tChild.getMenuId()))) {
-                recursionFn(list, tChild);
-            }
-        }
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java
deleted file mode 100644
index 2cb4e74..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package com.ruoyi.system.service.impl;
-
-import cn.hutool.core.util.ObjectUtil;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.core.utils.MapstructUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.system.domain.SysNotice;
-import com.ruoyi.system.domain.bo.SysNoticeBo;
-import com.ruoyi.system.domain.vo.SysNoticeVo;
-import com.ruoyi.system.domain.vo.SysUserVo;
-import com.ruoyi.system.mapper.SysNoticeMapper;
-import com.ruoyi.system.mapper.SysUserMapper;
-import com.ruoyi.system.service.ISysNoticeService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Service;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * 鍏憡 鏈嶅姟灞傚疄鐜�
- *
- * @author Lion Li
- */
-@RequiredArgsConstructor
-@Service
-public class SysNoticeServiceImpl implements ISysNoticeService {
-
-    private final SysNoticeMapper baseMapper;
-    private final SysUserMapper userMapper;
-
-    @Override
-    public TableDataInfo<SysNoticeVo> selectPageNoticeList(SysNoticeBo notice, PageQuery pageQuery) {
-        LambdaQueryWrapper<SysNotice> lqw = buildQueryWrapper(notice);
-        Page<SysNoticeVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw);
-        return TableDataInfo.build(page);
-    }
-
-    /**
-     * 鏌ヨ鍏憡淇℃伅
-     *
-     * @param noticeId 鍏憡ID
-     * @return 鍏憡淇℃伅
-     */
-    @Override
-    public SysNoticeVo selectNoticeById(Long noticeId) {
-        return baseMapper.selectVoById(noticeId);
-    }
-
-    /**
-     * 鏌ヨ鍏憡鍒楄〃
-     *
-     * @param notice 鍏憡淇℃伅
-     * @return 鍏憡闆嗗悎
-     */
-    @Override
-    public List<SysNoticeVo> selectNoticeList(SysNoticeBo notice) {
-        LambdaQueryWrapper<SysNotice> lqw = buildQueryWrapper(notice);
-        return baseMapper.selectVoList(lqw);
-    }
-
-    private LambdaQueryWrapper<SysNotice> buildQueryWrapper(SysNoticeBo bo) {
-        LambdaQueryWrapper<SysNotice> lqw = Wrappers.lambdaQuery();
-        lqw.like(StringUtils.isNotBlank(bo.getNoticeTitle()), SysNotice::getNoticeTitle, bo.getNoticeTitle());
-        lqw.eq(StringUtils.isNotBlank(bo.getNoticeType()), SysNotice::getNoticeType, bo.getNoticeType());
-        if (StringUtils.isNotBlank(bo.getCreateByName())) {
-            SysUserVo sysUser = userMapper.selectUserByUserName(bo.getCreateByName());
-            lqw.eq(SysNotice::getCreateBy, ObjectUtil.isNotNull(sysUser) ? sysUser.getUserId() : null);
-        }
-        return lqw;
-    }
-
-    /**
-     * 鏂板鍏憡
-     *
-     * @param bo 鍏憡淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    public int insertNotice(SysNoticeBo bo) {
-        SysNotice notice = MapstructUtils.convert(bo, SysNotice.class);
-        return baseMapper.insert(notice);
-    }
-
-    /**
-     * 淇敼鍏憡
-     *
-     * @param bo 鍏憡淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    public int updateNotice(SysNoticeBo bo) {
-        SysNotice notice = MapstructUtils.convert(bo, SysNotice.class);
-        return baseMapper.updateById(notice);
-    }
-
-    /**
-     * 鍒犻櫎鍏憡瀵硅薄
-     *
-     * @param noticeId 鍏憡ID
-     * @return 缁撴灉
-     */
-    @Override
-    public int deleteNoticeById(Long noticeId) {
-        return baseMapper.deleteById(noticeId);
-    }
-
-    /**
-     * 鎵归噺鍒犻櫎鍏憡淇℃伅
-     *
-     * @param noticeIds 闇�瑕佸垹闄ょ殑鍏憡ID
-     * @return 缁撴灉
-     */
-    @Override
-    public int deleteNoticeByIds(Long[] noticeIds) {
-        return baseMapper.deleteBatchIds(Arrays.asList(noticeIds));
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java
deleted file mode 100644
index abbedae..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package com.ruoyi.system.service.impl;
-
-import cn.hutool.core.util.ArrayUtil;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.core.utils.MapstructUtils;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.core.utils.ip.AddressUtils;
-import com.ruoyi.common.log.event.OperLogEvent;
-import com.ruoyi.system.domain.SysOperLog;
-import com.ruoyi.system.domain.bo.SysOperLogBo;
-import com.ruoyi.system.domain.vo.SysOperLogVo;
-import com.ruoyi.system.mapper.SysOperLogMapper;
-import com.ruoyi.system.service.ISysOperLogService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.context.event.EventListener;
-import org.springframework.scheduling.annotation.Async;
-import org.springframework.stereotype.Service;
-
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 鎿嶄綔鏃ュ織 鏈嶅姟灞傚鐞�
- *
- * @author Lion Li
- */
-@RequiredArgsConstructor
-@Service
-public class SysOperLogServiceImpl implements ISysOperLogService {
-
-    private final SysOperLogMapper baseMapper;
-
-    /**
-     * 鎿嶄綔鏃ュ織璁板綍
-     *
-     * @param operLogEvent 鎿嶄綔鏃ュ織浜嬩欢
-     */
-    @Async
-    @EventListener
-    public void recordOper(OperLogEvent operLogEvent) {
-        SysOperLogBo operLog = MapstructUtils.convert(operLogEvent, SysOperLogBo.class);
-        // 杩滅▼鏌ヨ鎿嶄綔鍦扮偣
-        operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
-        insertOperlog(operLog);
-    }
-
-    @Override
-    public TableDataInfo<SysOperLogVo> selectPageOperLogList(SysOperLogBo operLog, PageQuery pageQuery) {
-        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())
-            .between(params.get("beginTime") != null && params.get("endTime") != null,
-                SysOperLog::getOperTime, params.get("beginTime"), params.get("endTime"));
-        if (StringUtils.isBlank(pageQuery.getOrderByColumn())) {
-            pageQuery.setOrderByColumn("oper_id");
-            pageQuery.setIsAsc("desc");
-        }
-        Page<SysOperLogVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw);
-        return TableDataInfo.build(page);
-    }
-
-    /**
-     * 鏂板鎿嶄綔鏃ュ織
-     *
-     * @param bo 鎿嶄綔鏃ュ織瀵硅薄
-     */
-    @Override
-    public void insertOperlog(SysOperLogBo bo) {
-        SysOperLog operLog = MapstructUtils.convert(bo, SysOperLog.class);
-        operLog.setOperTime(new Date());
-        baseMapper.insert(operLog);
-    }
-
-    /**
-     * 鏌ヨ绯荤粺鎿嶄綔鏃ュ織闆嗗悎
-     *
-     * @param operLog 鎿嶄綔鏃ュ織瀵硅薄
-     * @return 鎿嶄綔鏃ュ織闆嗗悎
-     */
-    @Override
-    public List<SysOperLogVo> selectOperLogList(SysOperLogBo operLog) {
-        Map<String, Object> params = operLog.getParams();
-        return baseMapper.selectVoList(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())
-            .between(params.get("beginTime") != null && params.get("endTime") != null,
-                SysOperLog::getOperTime, params.get("beginTime"), params.get("endTime"))
-            .orderByDesc(SysOperLog::getOperId));
-    }
-
-    /**
-     * 鎵归噺鍒犻櫎绯荤粺鎿嶄綔鏃ュ織
-     *
-     * @param operIds 闇�瑕佸垹闄ょ殑鎿嶄綔鏃ュ織ID
-     * @return 缁撴灉
-     */
-    @Override
-    public int deleteOperLogByIds(Long[] operIds) {
-        return baseMapper.deleteBatchIds(Arrays.asList(operIds));
-    }
-
-    /**
-     * 鏌ヨ鎿嶄綔鏃ュ織璇︾粏
-     *
-     * @param operId 鎿嶄綔ID
-     * @return 鎿嶄綔鏃ュ織瀵硅薄
-     */
-    @Override
-    public SysOperLogVo selectOperLogById(Long operId) {
-        return baseMapper.selectVoById(operId);
-    }
-
-    /**
-     * 娓呯┖鎿嶄綔鏃ュ織
-     */
-    @Override
-    public void cleanOperLog() {
-        baseMapper.delete(new LambdaQueryWrapper<>());
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java
deleted file mode 100644
index 7031f71..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java
+++ /dev/null
@@ -1,183 +0,0 @@
-package com.ruoyi.system.service.impl;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.ObjectUtil;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.core.constant.CacheNames;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.utils.MapstructUtils;
-import com.ruoyi.common.core.utils.StreamUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.json.utils.JsonUtils;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.oss.constant.OssConstant;
-import com.ruoyi.common.redis.utils.CacheUtils;
-import com.ruoyi.common.redis.utils.RedisUtils;
-import com.ruoyi.common.tenant.core.TenantEntity;
-import com.ruoyi.common.tenant.helper.TenantHelper;
-import com.ruoyi.system.domain.SysOssConfig;
-import com.ruoyi.system.domain.bo.SysOssConfigBo;
-import com.ruoyi.system.domain.vo.SysOssConfigVo;
-import com.ruoyi.system.mapper.SysOssConfigMapper;
-import com.ruoyi.system.service.ISysOssConfigService;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 瀵硅薄瀛樺偍閰嶇疆Service涓氬姟灞傚鐞�
- *
- * @author Lion Li
- * @author 瀛よ垷鐑熼洦
- * @date 2021-08-13
- */
-@Slf4j
-@RequiredArgsConstructor
-@Service
-public class SysOssConfigServiceImpl implements ISysOssConfigService {
-
-    private final SysOssConfigMapper baseMapper;
-
-    /**
-     * 椤圭洰鍚姩鏃讹紝鍒濆鍖栧弬鏁板埌缂撳瓨锛屽姞杞介厤缃被
-     */
-    @Override
-    public void init() {
-        TenantHelper.enableIgnore();
-        List<SysOssConfig> list = baseMapper.selectList(
-                new LambdaQueryWrapper<SysOssConfig>().orderByAsc(TenantEntity::getTenantId));
-        TenantHelper.disableIgnore();
-        Map<String, List<SysOssConfig>> map = StreamUtils.groupByKey(list, SysOssConfig::getTenantId);
-        for (String tenantId : map.keySet()) {
-            TenantHelper.setDynamic(tenantId);
-            // 鍔犺浇OSS鍒濆鍖栭厤缃�
-            for (SysOssConfig config : map.get(tenantId)) {
-                String configKey = config.getConfigKey();
-                if ("0".equals(config.getStatus())) {
-                    RedisUtils.setCacheObject(OssConstant.DEFAULT_CONFIG_KEY, configKey);
-                }
-                CacheUtils.put(CacheNames.SYS_OSS_CONFIG, config.getConfigKey(), JsonUtils.toJsonString(config));
-            }
-        }
-        TenantHelper.clearDynamic();
-    }
-
-    @Override
-    public SysOssConfigVo queryById(Long ossConfigId) {
-        return baseMapper.selectVoById(ossConfigId);
-    }
-
-    @Override
-    public TableDataInfo<SysOssConfigVo> queryPageList(SysOssConfigBo bo, PageQuery pageQuery) {
-        LambdaQueryWrapper<SysOssConfig> lqw = buildQueryWrapper(bo);
-        Page<SysOssConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
-        return TableDataInfo.build(result);
-    }
-
-
-    private LambdaQueryWrapper<SysOssConfig> buildQueryWrapper(SysOssConfigBo bo) {
-        LambdaQueryWrapper<SysOssConfig> lqw = Wrappers.lambdaQuery();
-        lqw.eq(StringUtils.isNotBlank(bo.getConfigKey()), SysOssConfig::getConfigKey, bo.getConfigKey());
-        lqw.like(StringUtils.isNotBlank(bo.getBucketName()), SysOssConfig::getBucketName, bo.getBucketName());
-        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysOssConfig::getStatus, bo.getStatus());
-        return lqw;
-    }
-
-    @Override
-    public Boolean insertByBo(SysOssConfigBo bo) {
-        SysOssConfig config = MapstructUtils.convert(bo, SysOssConfig.class);
-        validEntityBeforeSave(config);
-        boolean flag = baseMapper.insert(config) > 0;
-        if (flag) {
-            CacheUtils.put(CacheNames.SYS_OSS_CONFIG, config.getConfigKey(), JsonUtils.toJsonString(config));
-        }
-        return flag;
-    }
-
-    @Override
-    public Boolean updateByBo(SysOssConfigBo bo) {
-        SysOssConfig config = MapstructUtils.convert(bo, SysOssConfig.class);
-        validEntityBeforeSave(config);
-        LambdaUpdateWrapper<SysOssConfig> luw = new LambdaUpdateWrapper<>();
-        luw.set(ObjectUtil.isNull(config.getPrefix()), SysOssConfig::getPrefix, "");
-        luw.set(ObjectUtil.isNull(config.getRegion()), SysOssConfig::getRegion, "");
-        luw.set(ObjectUtil.isNull(config.getExt1()), SysOssConfig::getExt1, "");
-        luw.set(ObjectUtil.isNull(config.getRemark()), SysOssConfig::getRemark, "");
-        luw.eq(SysOssConfig::getOssConfigId, config.getOssConfigId());
-        boolean flag = baseMapper.update(config, luw) > 0;
-        if (flag) {
-            CacheUtils.put(CacheNames.SYS_OSS_CONFIG, config.getConfigKey(), JsonUtils.toJsonString(config));
-        }
-        return flag;
-    }
-
-    /**
-     * 淇濆瓨鍓嶇殑鏁版嵁鏍¢獙
-     */
-    private void validEntityBeforeSave(SysOssConfig entity) {
-        if (StringUtils.isNotEmpty(entity.getConfigKey())
-            && !checkConfigKeyUnique(entity)) {
-            throw new ServiceException("鎿嶄綔閰嶇疆'" + entity.getConfigKey() + "'澶辫触, 閰嶇疆key宸插瓨鍦�!");
-        }
-    }
-
-    @Override
-    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
-        if (isValid) {
-            if (CollUtil.containsAny(ids, OssConstant.SYSTEM_DATA_IDS)) {
-                throw new ServiceException("绯荤粺鍐呯疆, 涓嶅彲鍒犻櫎!");
-            }
-        }
-        List<SysOssConfig> list = CollUtil.newArrayList();
-        for (Long configId : ids) {
-            SysOssConfig config = baseMapper.selectById(configId);
-            list.add(config);
-        }
-        boolean flag = baseMapper.deleteBatchIds(ids) > 0;
-        if (flag) {
-            list.forEach(sysOssConfig ->
-                CacheUtils.evict(CacheNames.SYS_OSS_CONFIG, sysOssConfig.getConfigKey()));
-        }
-        return flag;
-    }
-
-    /**
-     * 鍒ゆ柇configKey鏄惁鍞竴
-     */
-    private boolean checkConfigKeyUnique(SysOssConfig sysOssConfig) {
-        long ossConfigId = ObjectUtil.isNull(sysOssConfig.getOssConfigId()) ? -1L : sysOssConfig.getOssConfigId();
-        SysOssConfig info = baseMapper.selectOne(new LambdaQueryWrapper<SysOssConfig>()
-            .select(SysOssConfig::getOssConfigId, SysOssConfig::getConfigKey)
-            .eq(SysOssConfig::getConfigKey, sysOssConfig.getConfigKey()));
-        if (ObjectUtil.isNotNull(info) && info.getOssConfigId() != ossConfigId) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * 鍚敤绂佺敤鐘舵��
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public int updateOssConfigStatus(SysOssConfigBo bo) {
-        SysOssConfig sysOssConfig = MapstructUtils.convert(bo, SysOssConfig.class);
-        int row = baseMapper.update(null, new LambdaUpdateWrapper<SysOssConfig>()
-            .set(SysOssConfig::getStatus, "1"));
-        row += baseMapper.updateById(sysOssConfig);
-        if (row > 0) {
-            RedisUtils.setCacheObject(OssConstant.DEFAULT_CONFIG_KEY, sysOssConfig.getConfigKey());
-        }
-        return row;
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java
deleted file mode 100644
index 32dc9fd..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java
+++ /dev/null
@@ -1,171 +0,0 @@
-package com.ruoyi.system.service.impl;
-
-import cn.hutool.core.convert.Convert;
-import cn.hutool.core.io.IoUtil;
-import cn.hutool.core.util.ObjectUtil;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.core.constant.CacheNames;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.service.OssService;
-import com.ruoyi.common.core.utils.MapstructUtils;
-import com.ruoyi.common.core.utils.SpringUtils;
-import com.ruoyi.common.core.utils.StreamUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.core.utils.file.FileUtils;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.oss.core.OssClient;
-import com.ruoyi.common.oss.entity.UploadResult;
-import com.ruoyi.common.oss.enumd.AccessPolicyType;
-import com.ruoyi.common.oss.factory.OssFactory;
-import com.ruoyi.system.domain.SysOss;
-import com.ruoyi.system.domain.bo.SysOssBo;
-import com.ruoyi.system.domain.vo.SysOssVo;
-import com.ruoyi.system.mapper.SysOssMapper;
-import com.ruoyi.system.service.ISysOssService;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.RequiredArgsConstructor;
-import org.springframework.cache.annotation.Cacheable;
-import org.springframework.http.MediaType;
-import org.springframework.stereotype.Service;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.*;
-
-/**
- * 鏂囦欢涓婁紶 鏈嶅姟灞傚疄鐜�
- *
- * @author Lion Li
- */
-@RequiredArgsConstructor
-@Service
-public class SysOssServiceImpl implements ISysOssService, OssService {
-
-    private final SysOssMapper baseMapper;
-
-    @Override
-    public TableDataInfo<SysOssVo> queryPageList(SysOssBo bo, PageQuery pageQuery) {
-        LambdaQueryWrapper<SysOss> lqw = buildQueryWrapper(bo);
-        Page<SysOssVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
-        List<SysOssVo> filterResult = StreamUtils.toList(result.getRecords(), this::matchingUrl);
-        result.setRecords(filterResult);
-        return TableDataInfo.build(result);
-    }
-
-    @Override
-    public List<SysOssVo> listByIds(Collection<Long> ossIds) {
-        List<SysOssVo> list = new ArrayList<>();
-        for (Long id : ossIds) {
-            SysOssVo vo = SpringUtils.getAopProxy(this).getById(id);
-            if (ObjectUtil.isNotNull(vo)) {
-                list.add(this.matchingUrl(vo));
-            }
-        }
-        return list;
-    }
-
-    @Override
-    public String selectUrlByIds(String ossIds) {
-        List<String> list = new ArrayList<>();
-        for (Long id : StringUtils.splitTo(ossIds, Convert::toLong)) {
-            SysOssVo vo = SpringUtils.getAopProxy(this).getById(id);
-            if (ObjectUtil.isNotNull(vo)) {
-                list.add(this.matchingUrl(vo).getUrl());
-            }
-        }
-        return String.join(StringUtils.SEPARATOR, list);
-    }
-
-    private LambdaQueryWrapper<SysOss> buildQueryWrapper(SysOssBo bo) {
-        Map<String, Object> params = bo.getParams();
-        LambdaQueryWrapper<SysOss> lqw = Wrappers.lambdaQuery();
-        lqw.like(StringUtils.isNotBlank(bo.getFileName()), SysOss::getFileName, bo.getFileName());
-        lqw.like(StringUtils.isNotBlank(bo.getOriginalName()), SysOss::getOriginalName, bo.getOriginalName());
-        lqw.eq(StringUtils.isNotBlank(bo.getFileSuffix()), SysOss::getFileSuffix, bo.getFileSuffix());
-        lqw.eq(StringUtils.isNotBlank(bo.getUrl()), SysOss::getUrl, bo.getUrl());
-        lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
-            SysOss::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime"));
-        lqw.eq(ObjectUtil.isNotNull(bo.getCreateBy()), SysOss::getCreateBy, bo.getCreateBy());
-        lqw.eq(StringUtils.isNotBlank(bo.getService()), SysOss::getService, bo.getService());
-        return lqw;
-    }
-
-    @Cacheable(cacheNames = CacheNames.SYS_OSS, key = "#ossId")
-    @Override
-    public SysOssVo getById(Long ossId) {
-        return baseMapper.selectVoById(ossId);
-    }
-
-    @Override
-    public void download(Long ossId, HttpServletResponse response) throws IOException {
-        SysOssVo sysOss = SpringUtils.getAopProxy(this).getById(ossId);
-        if (ObjectUtil.isNull(sysOss)) {
-            throw new ServiceException("鏂囦欢鏁版嵁涓嶅瓨鍦�!");
-        }
-        FileUtils.setAttachmentResponseHeader(response, sysOss.getOriginalName());
-        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8");
-        OssClient storage = OssFactory.instance();
-        try(InputStream inputStream = storage.getObjectContent(sysOss.getUrl())) {
-            int available = inputStream.available();
-            IoUtil.copy(inputStream, response.getOutputStream(), available);
-            response.setContentLength(available);
-        } catch (Exception e) {
-            throw new ServiceException(e.getMessage());
-        }
-    }
-
-    @Override
-    public SysOssVo upload(MultipartFile file) {
-        String originalfileName = file.getOriginalFilename();
-        String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length());
-        OssClient storage = OssFactory.instance();
-        UploadResult uploadResult;
-        try {
-            uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType());
-        } catch (IOException e) {
-            throw new ServiceException(e.getMessage());
-        }
-        // 淇濆瓨鏂囦欢淇℃伅
-        SysOss oss = new SysOss();
-        oss.setUrl(uploadResult.getUrl());
-        oss.setFileSuffix(suffix);
-        oss.setFileName(uploadResult.getFilename());
-        oss.setOriginalName(originalfileName);
-        oss.setService(storage.getConfigKey());
-        baseMapper.insert(oss);
-        SysOssVo sysOssVo = MapstructUtils.convert(oss, SysOssVo.class);
-        return this.matchingUrl(sysOssVo);
-    }
-
-    @Override
-    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
-        if (isValid) {
-            // 鍋氫竴浜涗笟鍔′笂鐨勬牎楠�,鍒ゆ柇鏄惁闇�瑕佹牎楠�
-        }
-        List<SysOss> list = baseMapper.selectBatchIds(ids);
-        for (SysOss sysOss : list) {
-            OssClient storage = OssFactory.instance(sysOss.getService());
-            storage.delete(sysOss.getUrl());
-        }
-        return baseMapper.deleteBatchIds(ids) > 0;
-    }
-
-    /**
-     * 鍖归厤Url
-     *
-     * @param oss OSS瀵硅薄
-     * @return oss 鍖归厤Url鐨凮SS瀵硅薄
-     */
-    private SysOssVo matchingUrl(SysOssVo oss) {
-        OssClient storage = OssFactory.instance(oss.getService());
-        // 浠呬慨鏀规《绫诲瀷涓� private 鐨刄RL锛屼复鏃禪RL鏃堕暱涓�120s
-        if (AccessPolicyType.PRIVATE == storage.getAccessPolicy()) {
-            oss.setUrl(storage.getPrivateUrl(oss.getFileName(), 120));
-        }
-        return oss;
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPermissionServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPermissionServiceImpl.java
deleted file mode 100644
index ded956c..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPermissionServiceImpl.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.ruoyi.system.service.impl;
-
-import com.ruoyi.common.core.constant.TenantConstants;
-import com.ruoyi.common.satoken.utils.LoginHelper;
-import com.ruoyi.system.service.ISysMenuService;
-import com.ruoyi.system.service.ISysPermissionService;
-import com.ruoyi.system.service.ISysRoleService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Service;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * 鐢ㄦ埛鏉冮檺澶勭悊
- *
- * @author ruoyi
- */
-@RequiredArgsConstructor
-@Service
-public class SysPermissionServiceImpl implements ISysPermissionService {
-
-    private final ISysRoleService roleService;
-    private final ISysMenuService menuService;
-
-    /**
-     * 鑾峰彇瑙掕壊鏁版嵁鏉冮檺
-     *
-     * @param userId  鐢ㄦ埛id
-     * @return 瑙掕壊鏉冮檺淇℃伅
-     */
-    @Override
-    public Set<String> getRolePermission(Long userId) {
-        Set<String> roles = new HashSet<>();
-        // 绠$悊鍛樻嫢鏈夋墍鏈夋潈闄�
-        if (LoginHelper.isSuperAdmin(userId)) {
-            roles.add(TenantConstants.SUPER_ADMIN_ROLE_KEY);
-        } else {
-            roles.addAll(roleService.selectRolePermissionByUserId(userId));
-        }
-        return roles;
-    }
-
-    /**
-     * 鑾峰彇鑿滃崟鏁版嵁鏉冮檺
-     *
-     * @param userId  鐢ㄦ埛id
-     * @return 鑿滃崟鏉冮檺淇℃伅
-     */
-    @Override
-    public Set<String> getMenuPermission(Long userId) {
-        Set<String> perms = new HashSet<>();
-        // 绠$悊鍛樻嫢鏈夋墍鏈夋潈闄�
-        if (LoginHelper.isSuperAdmin(userId)) {
-            perms.add("*:*:*");
-        } else {
-            perms.addAll(menuService.selectMenuPermsByUserId(userId));
-        }
-        return perms;
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java
deleted file mode 100644
index 81e6dad..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java
+++ /dev/null
@@ -1,188 +0,0 @@
-package com.ruoyi.system.service.impl;
-
-import cn.hutool.core.util.ObjectUtil;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.utils.MapstructUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.system.domain.SysPost;
-import com.ruoyi.system.domain.SysUserPost;
-import com.ruoyi.system.domain.bo.SysPostBo;
-import com.ruoyi.system.domain.vo.SysPostVo;
-import com.ruoyi.system.mapper.SysPostMapper;
-import com.ruoyi.system.mapper.SysUserPostMapper;
-import com.ruoyi.system.service.ISysPostService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Service;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * 宀椾綅淇℃伅 鏈嶅姟灞傚鐞�
- *
- * @author Lion Li
- */
-@RequiredArgsConstructor
-@Service
-public class SysPostServiceImpl implements ISysPostService {
-
-    private final SysPostMapper baseMapper;
-    private final SysUserPostMapper userPostMapper;
-
-    @Override
-    public TableDataInfo<SysPostVo> selectPagePostList(SysPostBo post, PageQuery pageQuery) {
-        LambdaQueryWrapper<SysPost> lqw = buildQueryWrapper(post);
-        Page<SysPostVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw);
-        return TableDataInfo.build(page);
-    }
-
-    /**
-     * 鏌ヨ宀椾綅淇℃伅闆嗗悎
-     *
-     * @param post 宀椾綅淇℃伅
-     * @return 宀椾綅淇℃伅闆嗗悎
-     */
-    @Override
-    public List<SysPostVo> selectPostList(SysPostBo post) {
-        LambdaQueryWrapper<SysPost> lqw = buildQueryWrapper(post);
-        return baseMapper.selectVoList(lqw);
-    }
-
-    private LambdaQueryWrapper<SysPost> buildQueryWrapper(SysPostBo bo) {
-        LambdaQueryWrapper<SysPost> lqw = Wrappers.lambdaQuery();
-        lqw.like(StringUtils.isNotBlank(bo.getPostCode()), SysPost::getPostCode, bo.getPostCode());
-        lqw.like(StringUtils.isNotBlank(bo.getPostName()), SysPost::getPostName, bo.getPostName());
-        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysPost::getStatus, bo.getStatus());
-        lqw.orderByAsc(SysPost::getPostSort);
-        return lqw;
-    }
-
-    /**
-     * 鏌ヨ鎵�鏈夊矖浣�
-     *
-     * @return 宀椾綅鍒楄〃
-     */
-    @Override
-    public List<SysPostVo> selectPostAll() {
-        return baseMapper.selectVoList(new QueryWrapper<>());
-    }
-
-    /**
-     * 閫氳繃宀椾綅ID鏌ヨ宀椾綅淇℃伅
-     *
-     * @param postId 宀椾綅ID
-     * @return 瑙掕壊瀵硅薄淇℃伅
-     */
-    @Override
-    public SysPostVo selectPostById(Long postId) {
-        return baseMapper.selectVoById(postId);
-    }
-
-    /**
-     * 鏍规嵁鐢ㄦ埛ID鑾峰彇宀椾綅閫夋嫨妗嗗垪琛�
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 閫変腑宀椾綅ID鍒楄〃
-     */
-    @Override
-    public List<Long> selectPostListByUserId(Long userId) {
-        return baseMapper.selectPostListByUserId(userId);
-    }
-
-    /**
-     * 鏍¢獙宀椾綅鍚嶇О鏄惁鍞竴
-     *
-     * @param post 宀椾綅淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    public boolean checkPostNameUnique(SysPostBo post) {
-        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysPost>()
-            .eq(SysPost::getPostName, post.getPostName())
-            .ne(ObjectUtil.isNotNull(post.getPostId()), SysPost::getPostId, post.getPostId()));
-        return !exist;
-    }
-
-    /**
-     * 鏍¢獙宀椾綅缂栫爜鏄惁鍞竴
-     *
-     * @param post 宀椾綅淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    public boolean checkPostCodeUnique(SysPostBo post) {
-        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysPost>()
-            .eq(SysPost::getPostCode, post.getPostCode())
-            .ne(ObjectUtil.isNotNull(post.getPostId()), SysPost::getPostId, post.getPostId()));
-        return !exist;
-    }
-
-    /**
-     * 閫氳繃宀椾綅ID鏌ヨ宀椾綅浣跨敤鏁伴噺
-     *
-     * @param postId 宀椾綅ID
-     * @return 缁撴灉
-     */
-    @Override
-    public long countUserPostById(Long postId) {
-        return userPostMapper.selectCount(new LambdaQueryWrapper<SysUserPost>().eq(SysUserPost::getPostId, postId));
-    }
-
-    /**
-     * 鍒犻櫎宀椾綅淇℃伅
-     *
-     * @param postId 宀椾綅ID
-     * @return 缁撴灉
-     */
-    @Override
-    public int deletePostById(Long postId) {
-        return baseMapper.deleteById(postId);
-    }
-
-    /**
-     * 鎵归噺鍒犻櫎宀椾綅淇℃伅
-     *
-     * @param postIds 闇�瑕佸垹闄ょ殑宀椾綅ID
-     * @return 缁撴灉
-     */
-    @Override
-    public int deletePostByIds(Long[] postIds) {
-        for (Long postId : postIds) {
-            SysPost post = baseMapper.selectById(postId);
-            if (countUserPostById(postId) > 0) {
-                throw new ServiceException(String.format("%1$s宸插垎閰�,涓嶈兘鍒犻櫎", post.getPostName()));
-            }
-        }
-        return baseMapper.deleteBatchIds(Arrays.asList(postIds));
-    }
-
-    /**
-     * 鏂板淇濆瓨宀椾綅淇℃伅
-     *
-     * @param bo 宀椾綅淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    public int insertPost(SysPostBo bo) {
-        SysPost post = MapstructUtils.convert(bo, SysPost.class);
-        return baseMapper.insert(post);
-    }
-
-    /**
-     * 淇敼淇濆瓨宀椾綅淇℃伅
-     *
-     * @param bo 宀椾綅淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    public int updatePost(SysPostBo bo) {
-        SysPost post = MapstructUtils.convert(bo, SysPost.class);
-        return baseMapper.updateById(post);
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java
deleted file mode 100644
index 019d796..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java
+++ /dev/null
@@ -1,421 +0,0 @@
-package com.ruoyi.system.service.impl;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.ObjectUtil;
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.core.constant.UserConstants;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.utils.MapstructUtils;
-import com.ruoyi.common.core.utils.StreamUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.satoken.utils.LoginHelper;
-import com.ruoyi.system.domain.SysRole;
-import com.ruoyi.system.domain.SysRoleDept;
-import com.ruoyi.system.domain.SysRoleMenu;
-import com.ruoyi.system.domain.SysUserRole;
-import com.ruoyi.system.domain.bo.SysRoleBo;
-import com.ruoyi.system.domain.vo.SysRoleVo;
-import com.ruoyi.system.mapper.SysRoleDeptMapper;
-import com.ruoyi.system.mapper.SysRoleMapper;
-import com.ruoyi.system.mapper.SysRoleMenuMapper;
-import com.ruoyi.system.mapper.SysUserRoleMapper;
-import com.ruoyi.system.service.ISysRoleService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.*;
-
-/**
- * 瑙掕壊 涓氬姟灞傚鐞�
- *
- * @author Lion Li
- */
-@RequiredArgsConstructor
-@Service
-public class SysRoleServiceImpl implements ISysRoleService {
-
-    private final SysRoleMapper baseMapper;
-    private final SysRoleMenuMapper roleMenuMapper;
-    private final SysUserRoleMapper userRoleMapper;
-    private final SysRoleDeptMapper roleDeptMapper;
-
-    @Override
-    public TableDataInfo<SysRoleVo> selectPageRoleList(SysRoleBo role, PageQuery pageQuery) {
-        Page<SysRoleVo> page = baseMapper.selectPageRoleList(pageQuery.build(), this.buildQueryWrapper(role));
-        return TableDataInfo.build(page);
-    }
-
-    /**
-     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瑙掕壊鏁版嵁
-     *
-     * @param role 瑙掕壊淇℃伅
-     * @return 瑙掕壊鏁版嵁闆嗗悎淇℃伅
-     */
-    @Override
-    public List<SysRoleVo> selectRoleList(SysRoleBo role) {
-        return baseMapper.selectRoleList(this.buildQueryWrapper(role));
-    }
-
-    private Wrapper<SysRole> buildQueryWrapper(SysRoleBo bo) {
-        Map<String, Object> params = bo.getParams();
-        QueryWrapper<SysRole> wrapper = Wrappers.query();
-        wrapper.eq("r.del_flag", UserConstants.ROLE_NORMAL)
-            .eq(ObjectUtil.isNotNull(bo.getRoleId()), "r.role_id", bo.getRoleId())
-            .like(StringUtils.isNotBlank(bo.getRoleName()), "r.role_name", bo.getRoleName())
-            .eq(StringUtils.isNotBlank(bo.getStatus()), "r.status", bo.getStatus())
-            .like(StringUtils.isNotBlank(bo.getRoleKey()), "r.role_key", bo.getRoleKey())
-            .between(params.get("beginTime") != null && params.get("endTime") != null,
-                "r.create_time", params.get("beginTime"), params.get("endTime"))
-            .orderByAsc("r.role_sort").orderByAsc("r.create_time");;
-        return wrapper;
-    }
-
-    /**
-     * 鏍规嵁鐢ㄦ埛ID鏌ヨ瑙掕壊
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 瑙掕壊鍒楄〃
-     */
-    @Override
-    public List<SysRoleVo> selectRolesByUserId(Long userId) {
-        List<SysRoleVo> userRoles = baseMapper.selectRolePermissionByUserId(userId);
-        List<SysRoleVo> roles = selectRoleAll();
-        for (SysRoleVo role : roles) {
-            for (SysRoleVo userRole : userRoles) {
-                if (role.getRoleId().longValue() == userRole.getRoleId().longValue()) {
-                    role.setFlag(true);
-                    break;
-                }
-            }
-        }
-        return roles;
-    }
-
-    /**
-     * 鏍规嵁鐢ㄦ埛ID鏌ヨ鏉冮檺
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 鏉冮檺鍒楄〃
-     */
-    @Override
-    public Set<String> selectRolePermissionByUserId(Long userId) {
-        List<SysRoleVo> perms = baseMapper.selectRolePermissionByUserId(userId);
-        Set<String> permsSet = new HashSet<>();
-        for (SysRoleVo perm : perms) {
-            if (ObjectUtil.isNotNull(perm)) {
-                permsSet.addAll(StringUtils.splitList(perm.getRoleKey().trim()));
-            }
-        }
-        return permsSet;
-    }
-
-    /**
-     * 鏌ヨ鎵�鏈夎鑹�
-     *
-     * @return 瑙掕壊鍒楄〃
-     */
-    @Override
-    public List<SysRoleVo> selectRoleAll() {
-        return this.selectRoleList(new SysRoleBo());
-    }
-
-    /**
-     * 鏍规嵁鐢ㄦ埛ID鑾峰彇瑙掕壊閫夋嫨妗嗗垪琛�
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 閫変腑瑙掕壊ID鍒楄〃
-     */
-    @Override
-    public List<Long> selectRoleListByUserId(Long userId) {
-        return baseMapper.selectRoleListByUserId(userId);
-    }
-
-    /**
-     * 閫氳繃瑙掕壊ID鏌ヨ瑙掕壊
-     *
-     * @param roleId 瑙掕壊ID
-     * @return 瑙掕壊瀵硅薄淇℃伅
-     */
-    @Override
-    public SysRoleVo selectRoleById(Long roleId) {
-        return baseMapper.selectRoleById(roleId);
-    }
-
-    /**
-     * 鏍¢獙瑙掕壊鍚嶇О鏄惁鍞竴
-     *
-     * @param role 瑙掕壊淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    public boolean checkRoleNameUnique(SysRoleBo role) {
-        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysRole>()
-            .eq(SysRole::getRoleName, role.getRoleName())
-            .ne(ObjectUtil.isNotNull(role.getRoleId()), SysRole::getRoleId, role.getRoleId()));
-        return !exist;
-    }
-
-    /**
-     * 鏍¢獙瑙掕壊鏉冮檺鏄惁鍞竴
-     *
-     * @param role 瑙掕壊淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    public boolean checkRoleKeyUnique(SysRoleBo role) {
-        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysRole>()
-            .eq(SysRole::getRoleKey, role.getRoleKey())
-            .ne(ObjectUtil.isNotNull(role.getRoleId()), SysRole::getRoleId, role.getRoleId()));
-        return !exist;
-    }
-
-    /**
-     * 鏍¢獙瑙掕壊鏄惁鍏佽鎿嶄綔
-     *
-     * @param roleId 瑙掕壊ID
-     */
-    @Override
-    public void checkRoleAllowed(Long roleId) {
-        if (ObjectUtil.isNotNull(roleId) && LoginHelper.isSuperAdmin(roleId)) {
-            throw new ServiceException("涓嶅厑璁告搷浣滆秴绾х鐞嗗憳瑙掕壊");
-        }
-    }
-
-    /**
-     * 鏍¢獙瑙掕壊鏄惁鏈夋暟鎹潈闄�
-     *
-     * @param roleId 瑙掕壊id
-     */
-    @Override
-    public void checkRoleDataScope(Long roleId) {
-        if (ObjectUtil.isNull(roleId)) {
-            return;
-        }
-        if (LoginHelper.isSuperAdmin()) {
-            return;
-        }
-        List<SysRoleVo> roles = this.selectRoleList(new SysRoleBo(roleId));
-        if (CollUtil.isEmpty(roles)) {
-            throw new ServiceException("娌℃湁鏉冮檺璁块棶瑙掕壊鏁版嵁锛�");
-        }
-
-    }
-
-    /**
-     * 閫氳繃瑙掕壊ID鏌ヨ瑙掕壊浣跨敤鏁伴噺
-     *
-     * @param roleId 瑙掕壊ID
-     * @return 缁撴灉
-     */
-    @Override
-    public long countUserRoleByRoleId(Long roleId) {
-        return userRoleMapper.selectCount(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getRoleId, roleId));
-    }
-
-    /**
-     * 鏂板淇濆瓨瑙掕壊淇℃伅
-     *
-     * @param bo 瑙掕壊淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public int insertRole(SysRoleBo bo) {
-        SysRole role = MapstructUtils.convert(bo, SysRole.class);
-        // 鏂板瑙掕壊淇℃伅
-        baseMapper.insert(role);
-        bo.setRoleId(role.getRoleId());
-        return insertRoleMenu(bo);
-    }
-
-    /**
-     * 淇敼淇濆瓨瑙掕壊淇℃伅
-     *
-     * @param bo 瑙掕壊淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public int updateRole(SysRoleBo bo) {
-        SysRole role = MapstructUtils.convert(bo, SysRole.class);
-        // 淇敼瑙掕壊淇℃伅
-        baseMapper.updateById(role);
-        // 鍒犻櫎瑙掕壊涓庤彍鍗曞叧鑱�
-        roleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, role.getRoleId()));
-        return insertRoleMenu(bo);
-    }
-
-    /**
-     * 淇敼瑙掕壊鐘舵��
-     *
-     * @param roleId 瑙掕壊ID
-     * @param status 瑙掕壊鐘舵��
-     * @return 缁撴灉
-     */
-    @Override
-    public int updateRoleStatus(Long roleId, String status) {
-        return baseMapper.update(null,
-            new LambdaUpdateWrapper<SysRole>()
-                .set(SysRole::getStatus, status)
-                .eq(SysRole::getRoleId, roleId));
-    }
-
-    /**
-     * 淇敼鏁版嵁鏉冮檺淇℃伅
-     *
-     * @param bo 瑙掕壊淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public int authDataScope(SysRoleBo bo) {
-        SysRole role = MapstructUtils.convert(bo, SysRole.class);
-        // 淇敼瑙掕壊淇℃伅
-        baseMapper.updateById(role);
-        // 鍒犻櫎瑙掕壊涓庨儴闂ㄥ叧鑱�
-        roleDeptMapper.delete(new LambdaQueryWrapper<SysRoleDept>().eq(SysRoleDept::getRoleId, role.getRoleId()));
-        // 鏂板瑙掕壊鍜岄儴闂ㄤ俊鎭紙鏁版嵁鏉冮檺锛�
-        return insertRoleDept(bo);
-    }
-
-    /**
-     * 鏂板瑙掕壊鑿滃崟淇℃伅
-     *
-     * @param role 瑙掕壊瀵硅薄
-     */
-    private int insertRoleMenu(SysRoleBo role) {
-        int rows = 1;
-        // 鏂板鐢ㄦ埛涓庤鑹茬鐞�
-        List<SysRoleMenu> list = new ArrayList<SysRoleMenu>();
-        for (Long menuId : role.getMenuIds()) {
-            SysRoleMenu rm = new SysRoleMenu();
-            rm.setRoleId(role.getRoleId());
-            rm.setMenuId(menuId);
-            list.add(rm);
-        }
-        if (list.size() > 0) {
-            rows = roleMenuMapper.insertBatch(list) ? list.size() : 0;
-        }
-        return rows;
-    }
-
-    /**
-     * 鏂板瑙掕壊閮ㄩ棬淇℃伅(鏁版嵁鏉冮檺)
-     *
-     * @param role 瑙掕壊瀵硅薄
-     */
-    private int insertRoleDept(SysRoleBo role) {
-        int rows = 1;
-        // 鏂板瑙掕壊涓庨儴闂紙鏁版嵁鏉冮檺锛夌鐞�
-        List<SysRoleDept> list = new ArrayList<SysRoleDept>();
-        for (Long deptId : role.getDeptIds()) {
-            SysRoleDept rd = new SysRoleDept();
-            rd.setRoleId(role.getRoleId());
-            rd.setDeptId(deptId);
-            list.add(rd);
-        }
-        if (list.size() > 0) {
-            rows = roleDeptMapper.insertBatch(list) ? list.size() : 0;
-        }
-        return rows;
-    }
-
-    /**
-     * 閫氳繃瑙掕壊ID鍒犻櫎瑙掕壊
-     *
-     * @param roleId 瑙掕壊ID
-     * @return 缁撴灉
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public int deleteRoleById(Long roleId) {
-        // 鍒犻櫎瑙掕壊涓庤彍鍗曞叧鑱�
-        roleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, roleId));
-        // 鍒犻櫎瑙掕壊涓庨儴闂ㄥ叧鑱�
-        roleDeptMapper.delete(new LambdaQueryWrapper<SysRoleDept>().eq(SysRoleDept::getRoleId, roleId));
-        return baseMapper.deleteById(roleId);
-    }
-
-    /**
-     * 鎵归噺鍒犻櫎瑙掕壊淇℃伅
-     *
-     * @param roleIds 闇�瑕佸垹闄ょ殑瑙掕壊ID
-     * @return 缁撴灉
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public int deleteRoleByIds(Long[] roleIds) {
-        for (Long roleId : roleIds) {
-            checkRoleAllowed(roleId);
-            checkRoleDataScope(roleId);
-            SysRole role = baseMapper.selectById(roleId);
-            if (countUserRoleByRoleId(roleId) > 0) {
-                throw new ServiceException(String.format("%1$s宸插垎閰�,涓嶈兘鍒犻櫎", role.getRoleName()));
-            }
-        }
-        List<Long> ids = Arrays.asList(roleIds);
-        // 鍒犻櫎瑙掕壊涓庤彍鍗曞叧鑱�
-        roleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getRoleId, ids));
-        // 鍒犻櫎瑙掕壊涓庨儴闂ㄥ叧鑱�
-        roleDeptMapper.delete(new LambdaQueryWrapper<SysRoleDept>().in(SysRoleDept::getRoleId, ids));
-        return baseMapper.deleteBatchIds(ids);
-    }
-
-    /**
-     * 鍙栨秷鎺堟潈鐢ㄦ埛瑙掕壊
-     *
-     * @param userRole 鐢ㄦ埛鍜岃鑹插叧鑱斾俊鎭�
-     * @return 缁撴灉
-     */
-    @Override
-    public int deleteAuthUser(SysUserRole userRole) {
-        return userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
-            .eq(SysUserRole::getRoleId, userRole.getRoleId())
-            .eq(SysUserRole::getUserId, userRole.getUserId()));
-    }
-
-    /**
-     * 鎵归噺鍙栨秷鎺堟潈鐢ㄦ埛瑙掕壊
-     *
-     * @param roleId  瑙掕壊ID
-     * @param userIds 闇�瑕佸彇娑堟巿鏉冪殑鐢ㄦ埛鏁版嵁ID
-     * @return 缁撴灉
-     */
-    @Override
-    public int deleteAuthUsers(Long roleId, Long[] userIds) {
-        return userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
-            .eq(SysUserRole::getRoleId, roleId)
-            .in(SysUserRole::getUserId, Arrays.asList(userIds)));
-    }
-
-    /**
-     * 鎵归噺閫夋嫨鎺堟潈鐢ㄦ埛瑙掕壊
-     *
-     * @param roleId  瑙掕壊ID
-     * @param userIds 闇�瑕佹巿鏉冪殑鐢ㄦ埛鏁版嵁ID
-     * @return 缁撴灉
-     */
-    @Override
-    public int insertAuthUsers(Long roleId, Long[] userIds) {
-        // 鏂板鐢ㄦ埛涓庤鑹茬鐞�
-        int rows = 1;
-        List<SysUserRole> list = StreamUtils.toList(List.of(userIds), userId -> {
-            SysUserRole ur = new SysUserRole();
-            ur.setUserId(userId);
-            ur.setRoleId(roleId);
-            return ur;
-        });
-        if (CollUtil.isNotEmpty(list)) {
-            rows = userRoleMapper.insertBatch(list) ? list.size() : 0;
-        }
-        return rows;
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysSensitiveServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysSensitiveServiceImpl.java
deleted file mode 100644
index cab1f4c..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysSensitiveServiceImpl.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.ruoyi.system.service.impl;
-
-import com.ruoyi.common.satoken.utils.LoginHelper;
-import com.ruoyi.common.sensitive.core.SensitiveService;
-import org.springframework.stereotype.Service;
-
-/**
- * 鑴辨晱鏈嶅姟
- * 榛樿绠$悊鍛樹笉杩囨护
- * 闇�鑷鏍规嵁涓氬姟閲嶅啓瀹炵幇
- *
- * @author Lion Li
- * @version 3.6.0
- */
-@Service
-public class SysSensitiveServiceImpl implements SensitiveService {
-
-    /**
-     * 鏄惁鑴辨晱
-     */
-    @Override
-    public boolean isSensitive() {
-        return !LoginHelper.isSuperAdmin() || !LoginHelper.isTenantAdmin();
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTenantPackageServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTenantPackageServiceImpl.java
deleted file mode 100644
index 5ee03ea..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTenantPackageServiceImpl.java
+++ /dev/null
@@ -1,139 +0,0 @@
-package com.ruoyi.system.service.impl;
-
-import cn.hutool.core.collection.CollUtil;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.utils.MapstructUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.ruoyi.system.domain.SysTenant;
-import com.ruoyi.system.mapper.SysTenantMapper;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Service;
-import com.ruoyi.system.domain.bo.SysTenantPackageBo;
-import com.ruoyi.system.domain.vo.SysTenantPackageVo;
-import com.ruoyi.system.domain.SysTenantPackage;
-import com.ruoyi.system.mapper.SysTenantPackageMapper;
-import com.ruoyi.system.service.ISysTenantPackageService;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Collection;
-
-/**
- * 绉熸埛濂楅Service涓氬姟灞傚鐞�
- *
- * @author Michelle.Chung
- */
-@RequiredArgsConstructor
-@Service
-public class SysTenantPackageServiceImpl implements ISysTenantPackageService {
-
-    private final SysTenantPackageMapper baseMapper;
-    private final SysTenantMapper tenantMapper;
-
-    /**
-     * 鏌ヨ绉熸埛濂楅
-     */
-    @Override
-    public SysTenantPackageVo queryById(Long packageId){
-        return baseMapper.selectVoById(packageId);
-    }
-
-    /**
-     * 鏌ヨ绉熸埛濂楅鍒楄〃
-     */
-    @Override
-    public TableDataInfo<SysTenantPackageVo> queryPageList(SysTenantPackageBo bo, PageQuery pageQuery) {
-        LambdaQueryWrapper<SysTenantPackage> lqw = buildQueryWrapper(bo);
-        Page<SysTenantPackageVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
-        return TableDataInfo.build(result);
-    }
-
-    /**
-     * 鏌ヨ绉熸埛濂楅鍒楄〃
-     */
-    @Override
-    public List<SysTenantPackageVo> queryList(SysTenantPackageBo bo) {
-        LambdaQueryWrapper<SysTenantPackage> lqw = buildQueryWrapper(bo);
-        return baseMapper.selectVoList(lqw);
-    }
-
-    private LambdaQueryWrapper<SysTenantPackage> buildQueryWrapper(SysTenantPackageBo bo) {
-        Map<String, Object> params = bo.getParams();
-        LambdaQueryWrapper<SysTenantPackage> lqw = Wrappers.lambdaQuery();
-        lqw.like(StringUtils.isNotBlank(bo.getPackageName()), SysTenantPackage::getPackageName, bo.getPackageName());
-        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysTenantPackage::getStatus, bo.getStatus());
-        return lqw;
-    }
-
-    /**
-     * 鏂板绉熸埛濂楅
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public Boolean insertByBo(SysTenantPackageBo bo) {
-        SysTenantPackage add = MapstructUtils.convert(bo, SysTenantPackage.class);
-        // 淇濆瓨鑿滃崟id
-        List<Long> menuIds = Arrays.asList(bo.getMenuIds());
-        if (CollUtil.isNotEmpty(menuIds)) {
-            add.setMenuIds(StringUtils.join(menuIds, ", "));
-        } else {
-            add.setMenuIds("");
-        }
-        boolean flag = baseMapper.insert(add) > 0;
-        if (flag) {
-            bo.setPackageId(add.getPackageId());
-        }
-        return flag;
-    }
-
-    /**
-     * 淇敼绉熸埛濂楅
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public Boolean updateByBo(SysTenantPackageBo bo) {
-        SysTenantPackage update = MapstructUtils.convert(bo, SysTenantPackage.class);
-        // 淇濆瓨鑿滃崟id
-        List<Long> menuIds = Arrays.asList(bo.getMenuIds());
-        if (CollUtil.isNotEmpty(menuIds)) {
-            update.setMenuIds(StringUtils.join(menuIds, ", "));
-        } else {
-            update.setMenuIds("");
-        }
-        return baseMapper.updateById(update) > 0;
-    }
-
-    /**
-     * 淇敼濂楅鐘舵��
-     *
-     * @param bo 濂楅淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    public int updatePackageStatus(SysTenantPackageBo bo) {
-        SysTenantPackage tenantPackage = MapstructUtils.convert(bo, SysTenantPackage.class);
-        return baseMapper.updateById(tenantPackage);
-    }
-
-    /**
-     * 鎵归噺鍒犻櫎绉熸埛濂楅
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
-        if(isValid){
-            boolean exists = tenantMapper.exists(new LambdaQueryWrapper<SysTenant>().in(SysTenant::getPackageId, ids));
-            if (exists) {
-                throw new ServiceException("绉熸埛濂楅宸茶浣跨敤");
-            }
-        }
-        return baseMapper.deleteBatchIds(ids) > 0;
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTenantServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTenantServiceImpl.java
deleted file mode 100644
index 785e48c..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTenantServiceImpl.java
+++ /dev/null
@@ -1,375 +0,0 @@
-package com.ruoyi.system.service.impl;
-
-import cn.dev33.satoken.secure.BCrypt;
-import cn.hutool.core.convert.Convert;
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.RandomUtil;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.core.constant.CacheNames;
-import com.ruoyi.common.core.constant.Constants;
-import com.ruoyi.common.core.constant.TenantConstants;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.utils.MapstructUtils;
-import com.ruoyi.common.core.utils.SpringUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.tenant.helper.TenantHelper;
-import com.ruoyi.system.domain.*;
-import com.ruoyi.system.domain.bo.SysTenantBo;
-import com.ruoyi.system.domain.vo.SysTenantVo;
-import com.ruoyi.system.mapper.*;
-import com.ruoyi.system.service.ISysTenantService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.cache.annotation.CacheEvict;
-import org.springframework.cache.annotation.Cacheable;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-
-/**
- * 绉熸埛Service涓氬姟灞傚鐞�
- *
- * @author Michelle.Chung
- */
-@RequiredArgsConstructor
-@Service
-public class SysTenantServiceImpl implements ISysTenantService {
-
-    private final SysTenantMapper baseMapper;
-    private final SysTenantPackageMapper tenantPackageMapper;
-    private final SysUserMapper userMapper;
-    private final SysDeptMapper deptMapper;
-    private final SysRoleMapper roleMapper;
-    private final SysRoleMenuMapper roleMenuMapper;
-    private final SysRoleDeptMapper roleDeptMapper;
-    private final SysUserRoleMapper userRoleMapper;
-    private final SysDictTypeMapper dictTypeMapper;
-    private final SysDictDataMapper dictDataMapper;
-    private final SysConfigMapper configMapper;
-
-    /**
-     * 鏌ヨ绉熸埛
-     */
-    @Override
-    public SysTenantVo queryById(Long id) {
-        return baseMapper.selectVoById(id);
-    }
-
-    /**
-     * 鍩轰簬绉熸埛ID鏌ヨ绉熸埛
-     */
-    @Cacheable(cacheNames = CacheNames.SYS_TENANT, key = "#tenantId")
-    @Override
-    public SysTenantVo queryByTenantId(String tenantId) {
-        return baseMapper.selectVoOne(new LambdaQueryWrapper<SysTenant>().eq(SysTenant::getTenantId, tenantId));
-    }
-
-    /**
-     * 鏌ヨ绉熸埛鍒楄〃
-     */
-    @Override
-    public TableDataInfo<SysTenantVo> queryPageList(SysTenantBo bo, PageQuery pageQuery) {
-        LambdaQueryWrapper<SysTenant> lqw = buildQueryWrapper(bo);
-        Page<SysTenantVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
-        return TableDataInfo.build(result);
-    }
-
-    /**
-     * 鏌ヨ绉熸埛鍒楄〃
-     */
-    @Override
-    public List<SysTenantVo> queryList(SysTenantBo bo) {
-        LambdaQueryWrapper<SysTenant> lqw = buildQueryWrapper(bo);
-        return baseMapper.selectVoList(lqw);
-    }
-
-    private LambdaQueryWrapper<SysTenant> buildQueryWrapper(SysTenantBo bo) {
-        LambdaQueryWrapper<SysTenant> lqw = Wrappers.lambdaQuery();
-        lqw.eq(StringUtils.isNotBlank(bo.getTenantId()), SysTenant::getTenantId, bo.getTenantId());
-        lqw.like(StringUtils.isNotBlank(bo.getContactUserName()), SysTenant::getContactUserName, bo.getContactUserName());
-        lqw.eq(StringUtils.isNotBlank(bo.getContactPhone()), SysTenant::getContactPhone, bo.getContactPhone());
-        lqw.like(StringUtils.isNotBlank(bo.getCompanyName()), SysTenant::getCompanyName, bo.getCompanyName());
-        lqw.eq(StringUtils.isNotBlank(bo.getLicenseNumber()), SysTenant::getLicenseNumber, bo.getLicenseNumber());
-        lqw.eq(StringUtils.isNotBlank(bo.getAddress()), SysTenant::getAddress, bo.getAddress());
-        lqw.eq(StringUtils.isNotBlank(bo.getIntro()), SysTenant::getIntro, bo.getIntro());
-        lqw.like(StringUtils.isNotBlank(bo.getDomain()), SysTenant::getDomain, bo.getDomain());
-        lqw.eq(bo.getPackageId() != null, SysTenant::getPackageId, bo.getPackageId());
-        lqw.eq(bo.getExpireTime() != null, SysTenant::getExpireTime, bo.getExpireTime());
-        lqw.eq(bo.getAccountCount() != null, SysTenant::getAccountCount, bo.getAccountCount());
-        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysTenant::getStatus, bo.getStatus());
-        return lqw;
-    }
-
-    /**
-     * 鏂板绉熸埛
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public Boolean insertByBo(SysTenantBo bo) {
-        TenantHelper.enableIgnore();
-
-        SysTenant add = MapstructUtils.convert(bo, SysTenant.class);
-
-        // 鑾峰彇鎵�鏈夌鎴风紪鍙�
-        List<String> tenantIds = baseMapper.selectObjs(
-            new LambdaQueryWrapper<SysTenant>().select(SysTenant::getTenantId), Convert::toStr);
-        String tenantId = generateTenantId(tenantIds);
-        add.setTenantId(tenantId);
-        boolean flag = baseMapper.insert(add) > 0;
-        if (!flag) {
-            TenantHelper.disableIgnore();
-            throw new ServiceException("鍒涘缓绉熸埛澶辫触");
-        }
-        bo.setId(add.getId());
-
-        // 鏍规嵁濂楅鍒涘缓瑙掕壊
-        Long roleId = createTenantRole(tenantId, bo.getPackageId());
-
-        // 鍒涘缓閮ㄩ棬: 鍏徃鍚嶆槸閮ㄩ棬鍚嶇О
-        SysDept dept = new SysDept();
-        dept.setTenantId(tenantId);
-        dept.setDeptName(bo.getCompanyName());
-        dept.setLeader(bo.getUsername());
-        dept.setParentId(Constants.TOP_PARENT_ID);
-        dept.setAncestors(Constants.TOP_PARENT_ID.toString());
-        deptMapper.insert(dept);
-        Long deptId = dept.getDeptId();
-
-        // 瑙掕壊鍜岄儴闂ㄥ叧鑱旇〃
-        SysRoleDept roleDept = new SysRoleDept();
-        roleDept.setRoleId(roleId);
-        roleDept.setDeptId(deptId);
-        roleDeptMapper.insert(roleDept);
-
-        // 鍒涘缓绯荤粺鐢ㄦ埛
-        SysUser user = new SysUser();
-        user.setTenantId(tenantId);
-        user.setUserName(bo.getUsername());
-        user.setNickName(bo.getUsername());
-        user.setPassword(BCrypt.hashpw(bo.getPassword()));
-        user.setDeptId(deptId);
-        userMapper.insert(user);
-
-        // 鐢ㄦ埛鍜岃鑹插叧鑱旇〃
-        SysUserRole userRole = new SysUserRole();
-        userRole.setUserId(user.getUserId());
-        userRole.setRoleId(roleId);
-        userRoleMapper.insert(userRole);
-
-        String defaultTenantId = TenantConstants.DEFAULT_TENANT_ID;
-        List<SysDictType> dictTypeList = dictTypeMapper.selectList(
-            new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getTenantId, defaultTenantId));
-        List<SysDictData> dictDataList = dictDataMapper.selectList(
-            new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getTenantId, defaultTenantId));
-        for (SysDictType dictType : dictTypeList) {
-            dictType.setDictId(null);
-            dictType.setTenantId(tenantId);
-        }
-        for (SysDictData dictData : dictDataList) {
-            dictData.setDictCode(null);
-            dictData.setTenantId(tenantId);
-        }
-        dictTypeMapper.insertBatch(dictTypeList);
-        dictDataMapper.insertBatch(dictDataList);
-
-        List<SysConfig> sysConfigList = configMapper.selectList(
-            new LambdaQueryWrapper<SysConfig>().eq(SysConfig::getTenantId, defaultTenantId));
-        for (SysConfig config : sysConfigList) {
-            config.setConfigId(null);
-            config.setTenantId(tenantId);
-        }
-        configMapper.insertBatch(sysConfigList);
-
-        TenantHelper.disableIgnore();
-        return true;
-    }
-
-    /**
-     * 鐢熸垚绉熸埛id
-     *
-     * @param tenantIds 宸叉湁绉熸埛id鍒楄〃
-     * @return 绉熸埛id
-     */
-    private String generateTenantId(List<String> tenantIds) {
-        // 闅忔満鐢熸垚6浣�
-        String numbers = RandomUtil.randomNumbers(6);
-        // 鍒ゆ柇鏄惁瀛樺湪锛屽鏋滃瓨鍦ㄥ垯閲嶆柊鐢熸垚
-        if (tenantIds.contains(numbers)) {
-            generateTenantId(tenantIds);
-        }
-        return numbers;
-    }
-
-    /**
-     * 鏍规嵁绉熸埛鑿滃崟鍒涘缓绉熸埛瑙掕壊
-     *
-     * @param tenantId  绉熸埛缂栧彿
-     * @param packageId 绉熸埛濂楅id
-     * @return 瑙掕壊id
-     */
-    private Long createTenantRole(String tenantId, Long packageId) {
-        // 鑾峰彇绉熸埛濂楅
-        SysTenantPackage tenantPackage = tenantPackageMapper.selectById(packageId);
-        if (ObjectUtil.isNull(tenantPackage)) {
-            throw new ServiceException("濂楅涓嶅瓨鍦�");
-        }
-        // 鑾峰彇濂楅鑿滃崟id
-        List<Long> menuIds = StringUtils.splitTo(tenantPackage.getMenuIds(), Convert::toLong);
-
-        // 鍒涘缓瑙掕壊
-        SysRole role = new SysRole();
-        role.setTenantId(tenantId);
-        role.setRoleName(TenantConstants.TENANT_ADMIN_ROLE_NAME);
-        role.setRoleKey(TenantConstants.TENANT_ADMIN_ROLE_KEY);
-        role.setRoleSort(1);
-        role.setStatus(TenantConstants.NORMAL);
-        roleMapper.insert(role);
-        Long roleId = role.getRoleId();
-
-        // 鍒涘缓瑙掕壊鑿滃崟
-        List<SysRoleMenu> roleMenus = new ArrayList<>(menuIds.size());
-        menuIds.forEach(menuId -> {
-            SysRoleMenu roleMenu = new SysRoleMenu();
-            roleMenu.setRoleId(roleId);
-            roleMenu.setMenuId(menuId);
-            roleMenus.add(roleMenu);
-        });
-        roleMenuMapper.insertBatch(roleMenus);
-
-        return roleId;
-    }
-
-    /**
-     * 淇敼绉熸埛
-     */
-    @CacheEvict(cacheNames = CacheNames.SYS_TENANT, key = "#bo.tenantId")
-    @Override
-    public Boolean updateByBo(SysTenantBo bo) {
-        SysTenant tenant = MapstructUtils.convert(bo, SysTenant.class);
-        tenant.setTenantId(null);
-        tenant.setPackageId(null);
-        return baseMapper.updateById(tenant) > 0;
-    }
-
-    /**
-     * 淇敼绉熸埛鐘舵��
-     *
-     * @param bo 绉熸埛淇℃伅
-     * @return 缁撴灉
-     */
-    @CacheEvict(cacheNames = CacheNames.SYS_TENANT, key = "#bo.tenantId")
-    @Override
-    public int updateTenantStatus(SysTenantBo bo) {
-        SysTenant tenant = MapstructUtils.convert(bo, SysTenant.class);
-        return baseMapper.updateById(tenant);
-    }
-
-    /**
-     * 鏍¢獙绉熸埛鏄惁鍏佽鎿嶄綔
-     *
-     * @param tenantId 绉熸埛ID
-     */
-    @Override
-    public void checkTenantAllowed(String tenantId) {
-        if (ObjectUtil.isNotNull(tenantId) && TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) {
-            throw new ServiceException("涓嶅厑璁告搷浣滅鐞嗙鎴�");
-        }
-    }
-
-    /**
-     * 鎵归噺鍒犻櫎绉熸埛
-     */
-    @CacheEvict(cacheNames = CacheNames.SYS_TENANT, allEntries = true)
-    @Override
-    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
-        if (isValid) {
-            // 鍋氫竴浜涗笟鍔′笂鐨勬牎楠�,鍒ゆ柇鏄惁闇�瑕佹牎楠�
-            if (ids.contains(TenantConstants.SUPER_ADMIN_ID)) {
-                throw new ServiceException("瓒呯绉熸埛涓嶈兘鍒犻櫎");
-            }
-        }
-        return baseMapper.deleteBatchIds(ids) > 0;
-    }
-
-    /**
-     * 鏍¢獙浼佷笟鍚嶇О鏄惁鍞竴
-     */
-    @Override
-    public boolean checkCompanyNameUnique(SysTenantBo bo) {
-        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysTenant>()
-            .eq(SysTenant::getCompanyName, bo.getCompanyName())
-            .ne(ObjectUtil.isNotNull(bo.getTenantId()), SysTenant::getTenantId, bo.getTenantId()));
-        return !exist;
-    }
-
-    /**
-     * 鏍¢獙璐﹀彿浣欓
-     */
-    @Override
-    public boolean checkAccountBalance(String tenantId) {
-        SysTenantVo tenant = SpringUtils.getAopProxy(this).queryByTenantId(tenantId);
-        // 濡傛灉浣欓涓�-1浠h〃涓嶉檺鍒�
-        if (tenant.getAccountCount() == -1) {
-            return true;
-        }
-        Long userNumber = userMapper.selectCount(new LambdaQueryWrapper<>());
-        // 濡傛灉浣欓澶т簬0浠h〃杩樻湁鍙敤鍚嶉
-        return tenant.getAccountCount() - userNumber > 0;
-    }
-
-    /**
-     * 鏍¢獙鏈夋晥鏈�
-     */
-    @Override
-    public boolean checkExpireTime(String tenantId) {
-        SysTenantVo tenant = SpringUtils.getAopProxy(this).queryByTenantId(tenantId);
-        // 濡傛灉鏈缃繃鏈熸椂闂翠唬琛ㄤ笉闄愬埗
-        if (ObjectUtil.isNull(tenant.getExpireTime())) {
-            return true;
-        }
-        // 濡傛灉褰撳墠鏃堕棿鍦ㄨ繃鏈熸椂闂翠箣鍓嶅垯閫氳繃
-        return new Date().before(tenant.getExpireTime());
-    }
-
-    /**
-     * 鍚屾绉熸埛濂楅
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public Boolean syncTenantPackage(String tenantId, String packageId) {
-        TenantHelper.enableIgnore();
-        SysTenantPackage tenantPackage = tenantPackageMapper.selectById(packageId);
-        List<SysRole> roles = roleMapper.selectList(
-            new LambdaQueryWrapper<SysRole>().eq(SysRole::getTenantId, tenantId));
-        List<Long> roleIds = new ArrayList<>(roles.size() - 1);
-        List<Long> menuIds = StringUtils.splitTo(tenantPackage.getMenuIds(), Convert::toLong);
-        roles.forEach(item -> {
-            if (TenantConstants.TENANT_ADMIN_ROLE_KEY.equals(item.getRoleKey())) {
-                List<SysRoleMenu> roleMenus = new ArrayList<>(menuIds.size());
-                menuIds.forEach(menuId -> {
-                    SysRoleMenu roleMenu = new SysRoleMenu();
-                    roleMenu.setRoleId(item.getRoleId());
-                    roleMenu.setMenuId(menuId);
-                    roleMenus.add(roleMenu);
-                });
-                roleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, item.getRoleId()));
-                roleMenuMapper.insertBatch(roleMenus);
-            } else {
-                roleIds.add(item.getRoleId());
-            }
-        });
-        if (!roleIds.isEmpty()) {
-            roleMenuMapper.delete(
-                new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getRoleId, roleIds).notIn(!menuIds.isEmpty(), SysRoleMenu::getMenuId, menuIds));
-        }
-        TenantHelper.disableIgnore();
-        return true;
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
deleted file mode 100644
index e559a0e..0000000
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
+++ /dev/null
@@ -1,525 +0,0 @@
-package com.ruoyi.system.service.impl;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.ArrayUtil;
-import cn.hutool.core.util.ObjectUtil;
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.core.constant.CacheNames;
-import com.ruoyi.common.core.constant.UserConstants;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.service.UserService;
-import com.ruoyi.common.core.utils.MapstructUtils;
-import com.ruoyi.common.core.utils.StreamUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.mybatis.core.page.PageQuery;
-import com.ruoyi.common.mybatis.core.page.TableDataInfo;
-import com.ruoyi.common.mybatis.helper.DataBaseHelper;
-import com.ruoyi.common.satoken.utils.LoginHelper;
-import com.ruoyi.system.domain.SysDept;
-import com.ruoyi.system.domain.SysUser;
-import com.ruoyi.system.domain.SysUserPost;
-import com.ruoyi.system.domain.SysUserRole;
-import com.ruoyi.system.domain.bo.SysUserBo;
-import com.ruoyi.system.domain.vo.SysPostVo;
-import com.ruoyi.system.domain.vo.SysRoleVo;
-import com.ruoyi.system.domain.vo.SysUserVo;
-import com.ruoyi.system.mapper.*;
-import com.ruoyi.system.service.ISysUserService;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.cache.annotation.Cacheable;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * 鐢ㄦ埛 涓氬姟灞傚鐞�
- *
- * @author Lion Li
- */
-@Slf4j
-@RequiredArgsConstructor
-@Service
-public class SysUserServiceImpl implements ISysUserService, UserService {
-
-    private final SysUserMapper baseMapper;
-    private final SysDeptMapper deptMapper;
-    private final SysRoleMapper roleMapper;
-    private final SysPostMapper postMapper;
-    private final SysUserRoleMapper userRoleMapper;
-    private final SysUserPostMapper userPostMapper;
-
-    @Override
-    public TableDataInfo<SysUserVo> selectPageUserList(SysUserBo user, PageQuery pageQuery) {
-        Page<SysUserVo> page = baseMapper.selectPageUserList(pageQuery.build(), this.buildQueryWrapper(user));
-        return TableDataInfo.build(page);
-    }
-
-    /**
-     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ鐢ㄦ埛鍒楄〃
-     *
-     * @param user 鐢ㄦ埛淇℃伅
-     * @return 鐢ㄦ埛淇℃伅闆嗗悎淇℃伅
-     */
-    @Override
-    public List<SysUserVo> selectUserList(SysUserBo user) {
-        return baseMapper.selectUserList(this.buildQueryWrapper(user));
-    }
-
-    private Wrapper<SysUser> buildQueryWrapper(SysUserBo user) {
-        Map<String, Object> params = user.getParams();
-        QueryWrapper<SysUser> wrapper = Wrappers.query();
-        wrapper.eq("u.del_flag", UserConstants.USER_NORMAL)
-            .eq(ObjectUtil.isNotNull(user.getUserId()), "u.user_id", user.getUserId())
-            .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName())
-            .eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus())
-            .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber())
-            .between(params.get("beginTime") != null && params.get("endTime") != null,
-                "u.create_time", params.get("beginTime"), params.get("endTime"))
-            .and(ObjectUtil.isNotNull(user.getDeptId()), w -> {
-                List<SysDept> deptList = deptMapper.selectList(new LambdaQueryWrapper<SysDept>()
-                    .select(SysDept::getDeptId)
-                    .apply(DataBaseHelper.findInSet(user.getDeptId(), "ancestors")));
-                List<Long> ids = StreamUtils.toList(deptList, SysDept::getDeptId);
-                ids.add(user.getDeptId());
-                w.in("u.dept_id", ids);
-            });
-        return wrapper;
-    }
-
-    /**
-     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ宸插垎閰嶇敤鎴疯鑹插垪琛�
-     *
-     * @param user 鐢ㄦ埛淇℃伅
-     * @return 鐢ㄦ埛淇℃伅闆嗗悎淇℃伅
-     */
-    @Override
-    public TableDataInfo<SysUserVo> selectAllocatedList(SysUserBo user, PageQuery pageQuery) {
-        QueryWrapper<SysUser> wrapper = Wrappers.query();
-        wrapper.eq("u.del_flag", UserConstants.USER_NORMAL)
-            .eq(ObjectUtil.isNotNull(user.getRoleId()), "r.role_id", user.getRoleId())
-            .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName())
-            .eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus())
-            .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber());
-        Page<SysUserVo> page = baseMapper.selectAllocatedList(pageQuery.build(), wrapper);
-        return TableDataInfo.build(page);
-    }
-
-    /**
-     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ鏈垎閰嶇敤鎴疯鑹插垪琛�
-     *
-     * @param user 鐢ㄦ埛淇℃伅
-     * @return 鐢ㄦ埛淇℃伅闆嗗悎淇℃伅
-     */
-    @Override
-    public TableDataInfo<SysUserVo> selectUnallocatedList(SysUserBo user, PageQuery pageQuery) {
-        List<Long> userIds = userRoleMapper.selectUserIdsByRoleId(user.getRoleId());
-        QueryWrapper<SysUser> wrapper = Wrappers.query();
-        wrapper.eq("u.del_flag", UserConstants.USER_NORMAL)
-            .and(w -> w.ne("r.role_id", user.getRoleId()).or().isNull("r.role_id"))
-            .notIn(CollUtil.isNotEmpty(userIds), "u.user_id", userIds)
-            .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName())
-            .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber());
-        Page<SysUserVo> page = baseMapper.selectUnallocatedList(pageQuery.build(), wrapper);
-        return TableDataInfo.build(page);
-    }
-
-    /**
-     * 閫氳繃鐢ㄦ埛鍚嶆煡璇㈢敤鎴�
-     *
-     * @param userName 鐢ㄦ埛鍚�
-     * @return 鐢ㄦ埛瀵硅薄淇℃伅
-     */
-    @Override
-    public SysUserVo selectUserByUserName(String userName) {
-        return baseMapper.selectUserByUserName(userName);
-    }
-
-    /**
-     * 閫氳繃鎵嬫満鍙锋煡璇㈢敤鎴�
-     *
-     * @param phonenumber 鎵嬫満鍙�
-     * @return 鐢ㄦ埛瀵硅薄淇℃伅
-     */
-    @Override
-    public SysUserVo selectUserByPhonenumber(String phonenumber) {
-        return baseMapper.selectUserByPhonenumber(phonenumber);
-    }
-
-    /**
-     * 閫氳繃鐢ㄦ埛ID鏌ヨ鐢ㄦ埛
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 鐢ㄦ埛瀵硅薄淇℃伅
-     */
-    @Override
-    public SysUserVo selectUserById(Long userId) {
-        return baseMapper.selectUserById(userId);
-    }
-
-    /**
-     * 鏌ヨ鐢ㄦ埛鎵�灞炶鑹茬粍
-     *
-     * @param userName 鐢ㄦ埛鍚�
-     * @return 缁撴灉
-     */
-    @Override
-    public String selectUserRoleGroup(String userName) {
-        List<SysRoleVo> list = roleMapper.selectRolesByUserName(userName);
-        if (CollUtil.isEmpty(list)) {
-            return StringUtils.EMPTY;
-        }
-        return StreamUtils.join(list, SysRoleVo::getRoleName);
-    }
-
-    /**
-     * 鏌ヨ鐢ㄦ埛鎵�灞炲矖浣嶇粍
-     *
-     * @param userName 鐢ㄦ埛鍚�
-     * @return 缁撴灉
-     */
-    @Override
-    public String selectUserPostGroup(String userName) {
-        List<SysPostVo> list = postMapper.selectPostsByUserName(userName);
-        if (CollUtil.isEmpty(list)) {
-            return StringUtils.EMPTY;
-        }
-        return StreamUtils.join(list, SysPostVo::getPostName);
-    }
-
-    /**
-     * 鏍¢獙鐢ㄦ埛鍚嶇О鏄惁鍞竴
-     *
-     * @param user 鐢ㄦ埛淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    public boolean checkUserNameUnique(SysUserBo user) {
-        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
-            .eq(SysUser::getUserName, user.getUserName())
-            .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId()));
-        return !exist;
-    }
-
-    /**
-     * 鏍¢獙鎵嬫満鍙风爜鏄惁鍞竴
-     *
-     * @param user 鐢ㄦ埛淇℃伅
-     */
-    @Override
-    public boolean checkPhoneUnique(SysUserBo user) {
-        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
-            .eq(SysUser::getPhonenumber, user.getPhonenumber())
-            .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId()));
-        return !exist;
-    }
-
-    /**
-     * 鏍¢獙email鏄惁鍞竴
-     *
-     * @param user 鐢ㄦ埛淇℃伅
-     */
-    @Override
-    public boolean checkEmailUnique(SysUserBo user) {
-        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
-            .eq(SysUser::getEmail, user.getEmail())
-            .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId()));
-        return !exist;
-    }
-
-    /**
-     * 鏍¢獙鐢ㄦ埛鏄惁鍏佽鎿嶄綔
-     *
-     * @param userId 鐢ㄦ埛ID
-     */
-    @Override
-    public void checkUserAllowed(Long userId) {
-        if (ObjectUtil.isNotNull(userId) && LoginHelper.isSuperAdmin(userId)) {
-            throw new ServiceException("涓嶅厑璁告搷浣滆秴绾х鐞嗗憳鐢ㄦ埛");
-        }
-    }
-
-    /**
-     * 鏍¢獙鐢ㄦ埛鏄惁鏈夋暟鎹潈闄�
-     *
-     * @param userId 鐢ㄦ埛id
-     */
-    @Override
-    public void checkUserDataScope(Long userId) {
-        if (ObjectUtil.isNull(userId)) {
-            return;
-        }
-        if (LoginHelper.isSuperAdmin()) {
-            return;
-        }
-        if (ObjectUtil.isNull(baseMapper.selectUserById(userId))) {
-            throw new ServiceException("娌℃湁鏉冮檺璁块棶鐢ㄦ埛鏁版嵁锛�");
-        }
-    }
-
-    /**
-     * 鏂板淇濆瓨鐢ㄦ埛淇℃伅
-     *
-     * @param user 鐢ㄦ埛淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public int insertUser(SysUserBo user) {
-        SysUser sysUser = MapstructUtils.convert(user, SysUser.class);
-        // 鏂板鐢ㄦ埛淇℃伅
-        int rows = baseMapper.insert(sysUser);
-        user.setUserId(sysUser.getUserId());
-        // 鏂板鐢ㄦ埛宀椾綅鍏宠仈
-        insertUserPost(user, false);
-        // 鏂板鐢ㄦ埛涓庤鑹茬鐞�
-        insertUserRole(user, false);
-        return rows;
-    }
-
-    /**
-     * 娉ㄥ唽鐢ㄦ埛淇℃伅
-     *
-     * @param user 鐢ㄦ埛淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    public boolean registerUser(SysUserBo user, String tenantId) {
-        user.setCreateBy(user.getUserId());
-        user.setUpdateBy(user.getUserId());
-        SysUser sysUser = MapstructUtils.convert(user, SysUser.class);
-        sysUser.setTenantId(tenantId);
-        return baseMapper.insert(sysUser) > 0;
-    }
-
-    /**
-     * 淇敼淇濆瓨鐢ㄦ埛淇℃伅
-     *
-     * @param user 鐢ㄦ埛淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public int updateUser(SysUserBo user) {
-        // 鏂板鐢ㄦ埛涓庤鑹茬鐞�
-        insertUserRole(user, true);
-        // 鏂板鐢ㄦ埛涓庡矖浣嶇鐞�
-        insertUserPost(user, true);
-        SysUser sysUser = MapstructUtils.convert(user, SysUser.class);
-        // 闃叉閿欒鏇存柊鍚庡鑷寸殑鏁版嵁璇垹闄�
-        int flag = baseMapper.updateById(sysUser);
-        if (flag < 1) {
-            throw new ServiceException("淇敼鐢ㄦ埛" + user.getUserName() + "淇℃伅澶辫触");
-        }
-        return flag;
-    }
-
-    /**
-     * 鐢ㄦ埛鎺堟潈瑙掕壊
-     *
-     * @param userId  鐢ㄦ埛ID
-     * @param roleIds 瑙掕壊缁�
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void insertUserAuth(Long userId, Long[] roleIds) {
-        userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
-            .eq(SysUserRole::getUserId, userId));
-        insertUserRole(userId, roleIds, false);
-    }
-
-    /**
-     * 淇敼鐢ㄦ埛鐘舵��
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @param status 甯愬彿鐘舵��
-     * @return 缁撴灉
-     */
-    @Override
-    public int updateUserStatus(Long userId, String status) {
-        return baseMapper.update(null,
-            new LambdaUpdateWrapper<SysUser>()
-                .set(SysUser::getStatus, status)
-                .eq(SysUser::getUserId, userId));
-    }
-
-    /**
-     * 淇敼鐢ㄦ埛鍩烘湰淇℃伅
-     *
-     * @param user 鐢ㄦ埛淇℃伅
-     * @return 缁撴灉
-     */
-    @Override
-    public int updateUserProfile(SysUserBo user) {
-        return baseMapper.update(null,
-            new LambdaUpdateWrapper<SysUser>()
-                .set(ObjectUtil.isNotNull(user.getNickName()), SysUser::getNickName, user.getNickName())
-                .set(SysUser::getPhonenumber, user.getPhonenumber())
-                .set(SysUser::getEmail, user.getEmail())
-                .set(SysUser::getSex, user.getSex())
-                .eq(SysUser::getUserId, user.getUserId()));
-    }
-
-    /**
-     * 淇敼鐢ㄦ埛澶村儚
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @param avatar 澶村儚鍦板潃
-     * @return 缁撴灉
-     */
-    @Override
-    public boolean updateUserAvatar(Long userId, Long avatar) {
-        return baseMapper.update(null,
-            new LambdaUpdateWrapper<SysUser>()
-                .set(SysUser::getAvatar, avatar)
-                .eq(SysUser::getUserId, userId)) > 0;
-    }
-
-    /**
-     * 閲嶇疆鐢ㄦ埛瀵嗙爜
-     *
-     * @param userId   鐢ㄦ埛ID
-     * @param password 瀵嗙爜
-     * @return 缁撴灉
-     */
-    @Override
-    public int resetUserPwd(Long userId, String password) {
-        return baseMapper.update(null,
-            new LambdaUpdateWrapper<SysUser>()
-                .set(SysUser::getPassword, password)
-                .eq(SysUser::getUserId, userId));
-    }
-
-    /**
-     * 鏂板鐢ㄦ埛瑙掕壊淇℃伅
-     *
-     * @param user  鐢ㄦ埛瀵硅薄
-     * @param clear 娓呴櫎宸插瓨鍦ㄧ殑鍏宠仈鏁版嵁
-     */
-    private void insertUserRole(SysUserBo user, boolean clear) {
-        this.insertUserRole(user.getUserId(), user.getRoleIds(), clear);
-    }
-
-    /**
-     * 鏂板鐢ㄦ埛宀椾綅淇℃伅
-     *
-     * @param user  鐢ㄦ埛瀵硅薄
-     * @param clear 娓呴櫎宸插瓨鍦ㄧ殑鍏宠仈鏁版嵁
-     */
-    private void insertUserPost(SysUserBo user, boolean clear) {
-        Long[] posts = user.getPostIds();
-        if (ArrayUtil.isNotEmpty(posts)) {
-            if (clear) {
-                // 鍒犻櫎鐢ㄦ埛涓庡矖浣嶅叧鑱�
-                userPostMapper.delete(new LambdaQueryWrapper<SysUserPost>().eq(SysUserPost::getUserId, user.getUserId()));
-            }
-            // 鏂板鐢ㄦ埛涓庡矖浣嶇鐞�
-            List<SysUserPost> list = StreamUtils.toList(List.of(posts), postId -> {
-                SysUserPost up = new SysUserPost();
-                up.setUserId(user.getUserId());
-                up.setPostId(postId);
-                return up;
-            });
-            userPostMapper.insertBatch(list);
-        }
-    }
-
-    /**
-     * 鏂板鐢ㄦ埛瑙掕壊淇℃伅
-     *
-     * @param userId  鐢ㄦ埛ID
-     * @param roleIds 瑙掕壊缁�
-     * @param clear   娓呴櫎宸插瓨鍦ㄧ殑鍏宠仈鏁版嵁
-     */
-    private void insertUserRole(Long userId, Long[] roleIds, boolean clear) {
-        if (ArrayUtil.isNotEmpty(roleIds)) {
-            // 鍒ゆ柇鏄惁鍏锋湁姝よ鑹茬殑鎿嶄綔鏉冮檺
-            List<SysRoleVo> roles = roleMapper.selectRoleList(new LambdaQueryWrapper<>());
-            if (CollUtil.isEmpty(roles)) {
-                throw new ServiceException("娌℃湁鏉冮檺璁块棶瑙掕壊鐨勬暟鎹�");
-            }
-            List<Long> roleList = StreamUtils.toList(roles, SysRoleVo::getRoleId);
-            if (!LoginHelper.isSuperAdmin(userId)) {
-                roleList.remove(UserConstants.SUPER_ADMIN_ID);
-            }
-            List<Long> canDoRoleList = StreamUtils.filter(List.of(roleIds), roleList::contains);
-            if (CollUtil.isEmpty(canDoRoleList)) {
-                throw new ServiceException("娌℃湁鏉冮檺璁块棶瑙掕壊鐨勬暟鎹�");
-            }
-            if (clear) {
-                // 鍒犻櫎鐢ㄦ埛涓庤鑹插叧鑱�
-                userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
-            }
-            // 鏂板鐢ㄦ埛涓庤鑹茬鐞�
-            List<SysUserRole> list = StreamUtils.toList(canDoRoleList, roleId -> {
-                SysUserRole ur = new SysUserRole();
-                ur.setUserId(userId);
-                ur.setRoleId(roleId);
-                return ur;
-            });
-            userRoleMapper.insertBatch(list);
-        }
-    }
-
-    /**
-     * 閫氳繃鐢ㄦ埛ID鍒犻櫎鐢ㄦ埛
-     *
-     * @param userId 鐢ㄦ埛ID
-     * @return 缁撴灉
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public int deleteUserById(Long userId) {
-        // 鍒犻櫎鐢ㄦ埛涓庤鑹插叧鑱�
-        userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
-        // 鍒犻櫎鐢ㄦ埛涓庡矖浣嶈〃
-        userPostMapper.delete(new LambdaQueryWrapper<SysUserPost>().eq(SysUserPost::getUserId, userId));
-        // 闃叉鏇存柊澶辫触瀵艰嚧鐨勬暟鎹垹闄�
-        int flag = baseMapper.deleteById(userId);
-        if (flag < 1) {
-            throw new ServiceException("鍒犻櫎鐢ㄦ埛澶辫触!");
-        }
-        return flag;
-    }
-
-    /**
-     * 鎵归噺鍒犻櫎鐢ㄦ埛淇℃伅
-     *
-     * @param userIds 闇�瑕佸垹闄ょ殑鐢ㄦ埛ID
-     * @return 缁撴灉
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public int deleteUserByIds(Long[] userIds) {
-        for (Long userId : userIds) {
-            checkUserAllowed(userId);
-            checkUserDataScope(userId);
-        }
-        List<Long> ids = List.of(userIds);
-        // 鍒犻櫎鐢ㄦ埛涓庤鑹插叧鑱�
-        userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getUserId, ids));
-        // 鍒犻櫎鐢ㄦ埛涓庡矖浣嶈〃
-        userPostMapper.delete(new LambdaQueryWrapper<SysUserPost>().in(SysUserPost::getUserId, ids));
-        // 闃叉鏇存柊澶辫触瀵艰嚧鐨勬暟鎹垹闄�
-        int flag = baseMapper.deleteBatchIds(ids);
-        if (flag < 1) {
-            throw new ServiceException("鍒犻櫎鐢ㄦ埛澶辫触!");
-        }
-        return flag;
-    }
-
-    @Cacheable(cacheNames = CacheNames.SYS_USER_NAME, key = "#userId")
-    @Override
-    public String selectUserNameById(Long userId) {
-        SysUser sysUser = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>()
-            .select(SysUser::getUserName).eq(SysUser::getUserId, userId));
-        return ObjectUtil.isNull(sysUser) ? null : sysUser.getUserName();
-    }
-}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/CacheController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/CacheController.java
new file mode 100644
index 0000000..6b7499a
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/CacheController.java
@@ -0,0 +1,55 @@
+package org.dromara.system.controller.monitor;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.system.domain.vo.CacheListInfoVo;
+import lombok.RequiredArgsConstructor;
+import org.redisson.spring.data.connection.RedissonConnectionFactory;
+import org.springframework.data.redis.connection.RedisConnection;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.*;
+
+/**
+ * 缂撳瓨鐩戞帶
+ *
+ * @author Lion Li
+ */
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/monitor/cache")
+public class CacheController {
+
+    private final RedissonConnectionFactory connectionFactory;
+
+    /**
+     * 鑾峰彇缂撳瓨鐩戞帶鍒楄〃
+     */
+    @SaCheckPermission("monitor:cache:list")
+    @GetMapping()
+    public R<CacheListInfoVo> getInfo() throws Exception {
+        RedisConnection connection = connectionFactory.getConnection();
+        Properties commandStats = connection.commands().info("commandstats");
+
+        List<Map<String, String>> pieList = new ArrayList<>();
+        if (commandStats != null) {
+            commandStats.stringPropertyNames().forEach(key -> {
+                Map<String, String> data = new HashMap<>(2);
+                String property = commandStats.getProperty(key);
+                data.put("name", StringUtils.removeStart(key, "cmdstat_"));
+                data.put("value", StringUtils.substringBetween(property, "calls=", ",usec"));
+                pieList.add(data);
+            });
+        }
+
+        CacheListInfoVo infoVo = new CacheListInfoVo();
+        infoVo.setInfo(connection.commands().info());
+        infoVo.setDbSize(connection.commands().dbSize());
+        infoVo.setCommandStats(pieList);
+        return R.ok(infoVo);
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysLogininforController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysLogininforController.java
new file mode 100644
index 0000000..18e32d8
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysLogininforController.java
@@ -0,0 +1,89 @@
+package org.dromara.system.controller.monitor;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.common.core.constant.GlobalConstants;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.redis.utils.RedisUtils;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.system.domain.bo.SysLogininforBo;
+import org.dromara.system.domain.vo.SysLogininforVo;
+import org.dromara.system.service.ISysLogininforService;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 绯荤粺璁块棶璁板綍
+ *
+ * @author Lion Li
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/monitor/logininfor")
+public class SysLogininforController extends BaseController {
+
+    private final ISysLogininforService logininforService;
+
+    /**
+     * 鑾峰彇绯荤粺璁块棶璁板綍鍒楄〃
+     */
+    @SaCheckPermission("monitor:logininfor:list")
+    @GetMapping("/list")
+    public TableDataInfo<SysLogininforVo> list(SysLogininforBo logininfor, PageQuery pageQuery) {
+        return logininforService.selectPageLogininforList(logininfor, pageQuery);
+    }
+
+    /**
+     * 瀵煎嚭绯荤粺璁块棶璁板綍鍒楄〃
+     */
+    @Log(title = "鐧诲綍鏃ュ織", businessType = BusinessType.EXPORT)
+    @SaCheckPermission("monitor:logininfor:export")
+    @PostMapping("/export")
+    public void export(SysLogininforBo logininfor, HttpServletResponse response) {
+        List<SysLogininforVo> list = logininforService.selectLogininforList(logininfor);
+        ExcelUtil.exportExcel(list, "鐧诲綍鏃ュ織", SysLogininforVo.class, response);
+    }
+
+    /**
+     * 鎵归噺鍒犻櫎鐧诲綍鏃ュ織
+     * @param infoIds 鏃ュ織ids
+     */
+    @SaCheckPermission("monitor:logininfor:remove")
+    @Log(title = "鐧诲綍鏃ュ織", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{infoIds}")
+    public R<Void> remove(@PathVariable Long[] infoIds) {
+        return toAjax(logininforService.deleteLogininforByIds(infoIds));
+    }
+
+    /**
+     * 娓呯悊绯荤粺璁块棶璁板綍
+     */
+    @SaCheckPermission("monitor:logininfor:remove")
+    @Log(title = "鐧诲綍鏃ュ織", businessType = BusinessType.CLEAN)
+    @DeleteMapping("/clean")
+    public R<Void> clean() {
+        logininforService.cleanLogininfor();
+        return R.ok();
+    }
+
+    @SaCheckPermission("monitor:logininfor:unlock")
+    @Log(title = "璐︽埛瑙i攣", businessType = BusinessType.OTHER)
+    @GetMapping("/unlock/{userName}")
+    public R<Void> unlock(@PathVariable("userName") String userName) {
+        String loginName = GlobalConstants.PWD_ERR_CNT_KEY + userName;
+        if (RedisUtils.hasKey(loginName)) {
+            RedisUtils.deleteObject(loginName);
+        }
+        return R.ok();
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysOperlogController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysOperlogController.java
new file mode 100644
index 0000000..575aba6
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysOperlogController.java
@@ -0,0 +1,75 @@
+package org.dromara.system.controller.monitor;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.system.domain.bo.SysOperLogBo;
+import org.dromara.system.domain.vo.SysOperLogVo;
+import org.dromara.system.service.ISysOperLogService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import jakarta.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ * 鎿嶄綔鏃ュ織璁板綍
+ *
+ * @author Lion Li
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/monitor/operlog")
+public class SysOperlogController extends BaseController {
+
+    private final ISysOperLogService operLogService;
+
+    /**
+     * 鑾峰彇鎿嶄綔鏃ュ織璁板綍鍒楄〃
+     */
+    @SaCheckPermission("monitor:operlog:list")
+    @GetMapping("/list")
+    public TableDataInfo<SysOperLogVo> list(SysOperLogBo operLog, PageQuery pageQuery) {
+        return operLogService.selectPageOperLogList(operLog, pageQuery);
+    }
+
+    /**
+     * 瀵煎嚭鎿嶄綔鏃ュ織璁板綍鍒楄〃
+     */
+    @Log(title = "鎿嶄綔鏃ュ織", businessType = BusinessType.EXPORT)
+    @SaCheckPermission("monitor:operlog:export")
+    @PostMapping("/export")
+    public void export(SysOperLogBo operLog, HttpServletResponse response) {
+        List<SysOperLogVo> list = operLogService.selectOperLogList(operLog);
+        ExcelUtil.exportExcel(list, "鎿嶄綔鏃ュ織", SysOperLogVo.class, response);
+    }
+
+    /**
+     * 鎵归噺鍒犻櫎鎿嶄綔鏃ュ織璁板綍
+     * @param operIds 鏃ュ織ids
+     */
+    @Log(title = "鎿嶄綔鏃ュ織", businessType = BusinessType.DELETE)
+    @SaCheckPermission("monitor:operlog:remove")
+    @DeleteMapping("/{operIds}")
+    public R<Void> remove(@PathVariable Long[] operIds) {
+        return toAjax(operLogService.deleteOperLogByIds(operIds));
+    }
+
+    /**
+     * 娓呯悊鎿嶄綔鏃ュ織璁板綍
+     */
+    @Log(title = "鎿嶄綔鏃ュ織", businessType = BusinessType.CLEAN)
+    @SaCheckPermission("monitor:operlog:remove")
+    @DeleteMapping("/clean")
+    public R<Void> clean() {
+        operLogService.cleanOperLog();
+        return R.ok();
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysUserOnlineController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysUserOnlineController.java
new file mode 100644
index 0000000..0e626d0
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysUserOnlineController.java
@@ -0,0 +1,91 @@
+package org.dromara.system.controller.monitor;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.dev33.satoken.exception.NotLoginException;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.bean.BeanUtil;
+import org.dromara.common.core.constant.CacheConstants;
+import org.dromara.common.core.constant.GlobalConstants;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.domain.dto.UserOnlineDTO;
+import org.dromara.common.core.utils.StreamUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.redis.utils.RedisUtils;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.system.domain.SysUserOnline;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * 鍦ㄧ嚎鐢ㄦ埛鐩戞帶
+ *
+ * @author Lion Li
+ */
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/monitor/online")
+public class SysUserOnlineController extends BaseController {
+
+    /**
+     * 鑾峰彇鍦ㄧ嚎鐢ㄦ埛鐩戞帶鍒楄〃
+     *
+     * @param ipaddr   IP鍦板潃
+     * @param userName 鐢ㄦ埛鍚�
+     */
+    @SaCheckPermission("monitor:online:list")
+    @GetMapping("/list")
+    public TableDataInfo<SysUserOnline> list(String ipaddr, String userName) {
+        // 鑾峰彇鎵�鏈夋湭杩囨湡鐨� token
+        List<String> keys = StpUtil.searchTokenValue("", 0, -1, false);
+        List<UserOnlineDTO> userOnlineDTOList = new ArrayList<>();
+        for (String key : keys) {
+            String token = key.replace(GlobalConstants.LOGIN_TOKEN_KEY, "");
+            // 濡傛灉宸茬粡杩囨湡鍒欒烦杩�
+            if (StpUtil.stpLogic.getTokenActivityTimeoutByToken(token) < -1) {
+                continue;
+            }
+            userOnlineDTOList.add(RedisUtils.getCacheObject(CacheConstants.ONLINE_TOKEN_KEY + token));
+        }
+        if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) {
+            userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
+                StringUtils.equals(ipaddr, userOnline.getIpaddr()) &&
+                    StringUtils.equals(userName, userOnline.getUserName())
+            );
+        } else if (StringUtils.isNotEmpty(ipaddr)) {
+            userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
+                StringUtils.equals(ipaddr, userOnline.getIpaddr())
+            );
+        } else if (StringUtils.isNotEmpty(userName)) {
+            userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
+                StringUtils.equals(userName, userOnline.getUserName())
+            );
+        }
+        Collections.reverse(userOnlineDTOList);
+        userOnlineDTOList.removeAll(Collections.singleton(null));
+        List<SysUserOnline> userOnlineList = BeanUtil.copyToList(userOnlineDTOList, SysUserOnline.class);
+        return TableDataInfo.build(userOnlineList);
+    }
+
+    /**
+     * 寮洪��鐢ㄦ埛
+     *
+     * @param tokenId token鍊�
+     */
+    @SaCheckPermission("monitor:online:forceLogout")
+    @Log(title = "鍦ㄧ嚎鐢ㄦ埛", businessType = BusinessType.FORCE)
+    @DeleteMapping("/{tokenId}")
+    public R<Void> forceLogout(@PathVariable String tokenId) {
+        try {
+            StpUtil.kickoutByTokenValue(tokenId);
+        } catch (NotLoginException ignored) {
+        }
+        return R.ok();
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysConfigController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysConfigController.java
new file mode 100644
index 0000000..96a48bb
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysConfigController.java
@@ -0,0 +1,137 @@
+package org.dromara.system.controller.system;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.system.domain.bo.SysConfigBo;
+import org.dromara.system.domain.vo.SysConfigVo;
+import org.dromara.system.service.ISysConfigService;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 鍙傛暟閰嶇疆 淇℃伅鎿嶄綔澶勭悊
+ *
+ * @author Lion Li
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/system/config")
+public class SysConfigController extends BaseController {
+
+    private final ISysConfigService configService;
+
+    /**
+     * 鑾峰彇鍙傛暟閰嶇疆鍒楄〃
+     */
+    @SaCheckPermission("system:config:list")
+    @GetMapping("/list")
+    public TableDataInfo<SysConfigVo> list(SysConfigBo config, PageQuery pageQuery) {
+        return configService.selectPageConfigList(config, pageQuery);
+    }
+
+    /**
+     * 瀵煎嚭鍙傛暟閰嶇疆鍒楄〃
+     */
+    @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.EXPORT)
+    @SaCheckPermission("system:config:export")
+    @PostMapping("/export")
+    public void export(SysConfigBo config, HttpServletResponse response) {
+        List<SysConfigVo> list = configService.selectConfigList(config);
+        ExcelUtil.exportExcel(list, "鍙傛暟鏁版嵁", SysConfigVo.class, response);
+    }
+
+    /**
+     * 鏍规嵁鍙傛暟缂栧彿鑾峰彇璇︾粏淇℃伅
+     *
+     * @param configId 鍙傛暟ID
+     */
+    @SaCheckPermission("system:config:query")
+    @GetMapping(value = "/{configId}")
+    public R<SysConfigVo> getInfo(@PathVariable Long configId) {
+        return R.ok(configService.selectConfigById(configId));
+    }
+
+    /**
+     * 鏍规嵁鍙傛暟閿悕鏌ヨ鍙傛暟鍊�
+     *
+     * @param configKey 鍙傛暟Key
+     */
+    @GetMapping(value = "/configKey/{configKey}")
+    public R<Void> getConfigKey(@PathVariable String configKey) {
+        return R.ok(configService.selectConfigByKey(configKey));
+    }
+
+    /**
+     * 鏂板鍙傛暟閰嶇疆
+     */
+    @SaCheckPermission("system:config:add")
+    @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.INSERT)
+    @PostMapping
+    public R<Void> add(@Validated @RequestBody SysConfigBo config) {
+        if (!configService.checkConfigKeyUnique(config)) {
+            return R.fail("鏂板鍙傛暟'" + config.getConfigName() + "'澶辫触锛屽弬鏁伴敭鍚嶅凡瀛樺湪");
+        }
+        configService.insertConfig(config);
+        return R.ok();
+    }
+
+    /**
+     * 淇敼鍙傛暟閰嶇疆
+     */
+    @SaCheckPermission("system:config:edit")
+    @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public R<Void> edit(@Validated @RequestBody SysConfigBo config) {
+        if (!configService.checkConfigKeyUnique(config)) {
+            return R.fail("淇敼鍙傛暟'" + config.getConfigName() + "'澶辫触锛屽弬鏁伴敭鍚嶅凡瀛樺湪");
+        }
+        configService.updateConfig(config);
+        return R.ok();
+    }
+
+    /**
+     * 鏍规嵁鍙傛暟閿悕淇敼鍙傛暟閰嶇疆
+     */
+    @SaCheckPermission("system:config:edit")
+    @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.UPDATE)
+    @PutMapping("/updateByKey")
+    public R<Void> updateByKey(@RequestBody SysConfigBo config) {
+        configService.updateConfig(config);
+        return R.ok();
+    }
+
+    /**
+     * 鍒犻櫎鍙傛暟閰嶇疆
+     *
+     * @param configIds 鍙傛暟ID涓�
+     */
+    @SaCheckPermission("system:config:remove")
+    @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{configIds}")
+    public R<Void> remove(@PathVariable Long[] configIds) {
+        configService.deleteConfigByIds(configIds);
+        return R.ok();
+    }
+
+    /**
+     * 鍒锋柊鍙傛暟缂撳瓨
+     */
+    @SaCheckPermission("system:config:remove")
+    @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.CLEAN)
+    @DeleteMapping("/refreshCache")
+    public R<Void> refreshCache() {
+        configService.resetConfigCache();
+        return R.ok();
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysDeptController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysDeptController.java
new file mode 100644
index 0000000..478ac6e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysDeptController.java
@@ -0,0 +1,120 @@
+package org.dromara.system.controller.system;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.hutool.core.convert.Convert;
+import org.dromara.common.core.constant.UserConstants;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.system.domain.bo.SysDeptBo;
+import org.dromara.system.domain.vo.SysDeptVo;
+import org.dromara.system.service.ISysDeptService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 閮ㄩ棬淇℃伅
+ *
+ * @author Lion Li
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/system/dept")
+public class SysDeptController extends BaseController {
+
+    private final ISysDeptService deptService;
+
+    /**
+     * 鑾峰彇閮ㄩ棬鍒楄〃
+     */
+    @SaCheckPermission("system:dept:list")
+    @GetMapping("/list")
+    public R<List<SysDeptVo>> list(SysDeptBo dept) {
+        List<SysDeptVo> depts = deptService.selectDeptList(dept);
+        return R.ok(depts);
+    }
+
+    /**
+     * 鏌ヨ閮ㄩ棬鍒楄〃锛堟帓闄よ妭鐐癸級
+     *
+     * @param deptId 閮ㄩ棬ID
+     */
+    @SaCheckPermission("system:dept:list")
+    @GetMapping("/list/exclude/{deptId}")
+    public R<List<SysDeptVo>> excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) {
+        List<SysDeptVo> depts = deptService.selectDeptList(new SysDeptBo());
+        depts.removeIf(d -> d.getDeptId().equals(deptId)
+            || StringUtils.splitList(d.getAncestors()).contains(Convert.toStr(deptId)));
+        return R.ok(depts);
+    }
+
+    /**
+     * 鏍规嵁閮ㄩ棬缂栧彿鑾峰彇璇︾粏淇℃伅
+     *
+     * @param deptId 閮ㄩ棬ID
+     */
+    @SaCheckPermission("system:dept:query")
+    @GetMapping(value = "/{deptId}")
+    public R<SysDeptVo> getInfo(@PathVariable Long deptId) {
+        deptService.checkDeptDataScope(deptId);
+        return R.ok(deptService.selectDeptById(deptId));
+    }
+
+    /**
+     * 鏂板閮ㄩ棬
+     */
+    @SaCheckPermission("system:dept:add")
+    @Log(title = "閮ㄩ棬绠$悊", businessType = BusinessType.INSERT)
+    @PostMapping
+    public R<Void> add(@Validated @RequestBody SysDeptBo dept) {
+        if (!deptService.checkDeptNameUnique(dept)) {
+            return R.fail("鏂板閮ㄩ棬'" + dept.getDeptName() + "'澶辫触锛岄儴闂ㄥ悕绉板凡瀛樺湪");
+        }
+        return toAjax(deptService.insertDept(dept));
+    }
+
+    /**
+     * 淇敼閮ㄩ棬
+     */
+    @SaCheckPermission("system:dept:edit")
+    @Log(title = "閮ㄩ棬绠$悊", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public R<Void> edit(@Validated @RequestBody SysDeptBo dept) {
+        Long deptId = dept.getDeptId();
+        deptService.checkDeptDataScope(deptId);
+        if (!deptService.checkDeptNameUnique(dept)) {
+            return R.fail("淇敼閮ㄩ棬'" + dept.getDeptName() + "'澶辫触锛岄儴闂ㄥ悕绉板凡瀛樺湪");
+        } else if (dept.getParentId().equals(deptId)) {
+            return R.fail("淇敼閮ㄩ棬'" + dept.getDeptName() + "'澶辫触锛屼笂绾ч儴闂ㄤ笉鑳芥槸鑷繁");
+        } else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus())
+            && deptService.selectNormalChildrenDeptById(deptId) > 0) {
+            return R.fail("璇ラ儴闂ㄥ寘鍚湭鍋滅敤鐨勫瓙閮ㄩ棬锛�");
+        }
+        return toAjax(deptService.updateDept(dept));
+    }
+
+    /**
+     * 鍒犻櫎閮ㄩ棬
+     *
+     * @param deptId 閮ㄩ棬ID
+     */
+    @SaCheckPermission("system:dept:remove")
+    @Log(title = "閮ㄩ棬绠$悊", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{deptId}")
+    public R<Void> remove(@PathVariable Long deptId) {
+        if (deptService.hasChildByDeptId(deptId)) {
+            return R.warn("瀛樺湪涓嬬骇閮ㄩ棬,涓嶅厑璁稿垹闄�");
+        }
+        if (deptService.checkDeptExistUser(deptId)) {
+            return R.warn("閮ㄩ棬瀛樺湪鐢ㄦ埛,涓嶅厑璁稿垹闄�");
+        }
+        deptService.checkDeptDataScope(deptId);
+        return toAjax(deptService.deleteDeptById(deptId));
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysDictDataController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysDictDataController.java
new file mode 100644
index 0000000..cc8034e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysDictDataController.java
@@ -0,0 +1,117 @@
+package org.dromara.system.controller.system;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.hutool.core.util.ObjectUtil;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.system.domain.bo.SysDictDataBo;
+import org.dromara.system.domain.vo.SysDictDataVo;
+import org.dromara.system.service.ISysDictDataService;
+import org.dromara.system.service.ISysDictTypeService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import jakarta.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 鏁版嵁瀛楀吀淇℃伅
+ *
+ * @author Lion Li
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/system/dict/data")
+public class SysDictDataController extends BaseController {
+
+    private final ISysDictDataService dictDataService;
+    private final ISysDictTypeService dictTypeService;
+
+    /**
+     * 鏌ヨ瀛楀吀鏁版嵁鍒楄〃
+     */
+    @SaCheckPermission("system:dict:list")
+    @GetMapping("/list")
+    public TableDataInfo<SysDictDataVo> list(SysDictDataBo dictData, PageQuery pageQuery) {
+        return dictDataService.selectPageDictDataList(dictData, pageQuery);
+    }
+
+    /**
+     * 瀵煎嚭瀛楀吀鏁版嵁鍒楄〃
+     */
+    @Log(title = "瀛楀吀鏁版嵁", businessType = BusinessType.EXPORT)
+    @SaCheckPermission("system:dict:export")
+    @PostMapping("/export")
+    public void export(SysDictDataBo dictData, HttpServletResponse response) {
+        List<SysDictDataVo> list = dictDataService.selectDictDataList(dictData);
+        ExcelUtil.exportExcel(list, "瀛楀吀鏁版嵁", SysDictDataVo.class, response);
+    }
+
+    /**
+     * 鏌ヨ瀛楀吀鏁版嵁璇︾粏
+     *
+     * @param dictCode 瀛楀吀code
+     */
+    @SaCheckPermission("system:dict:query")
+    @GetMapping(value = "/{dictCode}")
+    public R<SysDictDataVo> getInfo(@PathVariable Long dictCode) {
+        return R.ok(dictDataService.selectDictDataById(dictCode));
+    }
+
+    /**
+     * 鏍规嵁瀛楀吀绫诲瀷鏌ヨ瀛楀吀鏁版嵁淇℃伅
+     *
+     * @param dictType 瀛楀吀绫诲瀷
+     */
+    @GetMapping(value = "/type/{dictType}")
+    public R<List<SysDictDataVo>> dictType(@PathVariable String dictType) {
+        List<SysDictDataVo> data = dictTypeService.selectDictDataByType(dictType);
+        if (ObjectUtil.isNull(data)) {
+            data = new ArrayList<>();
+        }
+        return R.ok(data);
+    }
+
+    /**
+     * 鏂板瀛楀吀绫诲瀷
+     */
+    @SaCheckPermission("system:dict:add")
+    @Log(title = "瀛楀吀鏁版嵁", businessType = BusinessType.INSERT)
+    @PostMapping
+    public R<Void> add(@Validated @RequestBody SysDictDataBo dict) {
+        dictDataService.insertDictData(dict);
+        return R.ok();
+    }
+
+    /**
+     * 淇敼淇濆瓨瀛楀吀绫诲瀷
+     */
+    @SaCheckPermission("system:dict:edit")
+    @Log(title = "瀛楀吀鏁版嵁", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public R<Void> edit(@Validated @RequestBody SysDictDataBo dict) {
+        dictDataService.updateDictData(dict);
+        return R.ok();
+    }
+
+    /**
+     * 鍒犻櫎瀛楀吀绫诲瀷
+     *
+     * @param dictCodes 瀛楀吀code涓�
+     */
+    @SaCheckPermission("system:dict:remove")
+    @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{dictCodes}")
+    public R<Void> remove(@PathVariable Long[] dictCodes) {
+        dictDataService.deleteDictDataByIds(dictCodes);
+        return R.ok();
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysDictTypeController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysDictTypeController.java
new file mode 100644
index 0000000..67c1f51
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysDictTypeController.java
@@ -0,0 +1,125 @@
+package org.dromara.system.controller.system;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.system.domain.bo.SysDictTypeBo;
+import org.dromara.system.domain.vo.SysDictTypeVo;
+import org.dromara.system.service.ISysDictTypeService;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 鏁版嵁瀛楀吀淇℃伅
+ *
+ * @author Lion Li
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/system/dict/type")
+public class SysDictTypeController extends BaseController {
+
+    private final ISysDictTypeService dictTypeService;
+
+    /**
+     * 鏌ヨ瀛楀吀绫诲瀷鍒楄〃
+     */
+    @SaCheckPermission("system:dict:list")
+    @GetMapping("/list")
+    public TableDataInfo<SysDictTypeVo> list(SysDictTypeBo dictType, PageQuery pageQuery) {
+        return dictTypeService.selectPageDictTypeList(dictType, pageQuery);
+    }
+
+    /**
+     * 瀵煎嚭瀛楀吀绫诲瀷鍒楄〃
+     */
+    @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.EXPORT)
+    @SaCheckPermission("system:dict:export")
+    @PostMapping("/export")
+    public void export(SysDictTypeBo dictType, HttpServletResponse response) {
+        List<SysDictTypeVo> list = dictTypeService.selectDictTypeList(dictType);
+        ExcelUtil.exportExcel(list, "瀛楀吀绫诲瀷", SysDictTypeVo.class, response);
+    }
+
+    /**
+     * 鏌ヨ瀛楀吀绫诲瀷璇︾粏
+     *
+     * @param dictId 瀛楀吀ID
+     */
+    @SaCheckPermission("system:dict:query")
+    @GetMapping(value = "/{dictId}")
+    public R<SysDictTypeVo> getInfo(@PathVariable Long dictId) {
+        return R.ok(dictTypeService.selectDictTypeById(dictId));
+    }
+
+    /**
+     * 鏂板瀛楀吀绫诲瀷
+     */
+    @SaCheckPermission("system:dict:add")
+    @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.INSERT)
+    @PostMapping
+    public R<Void> add(@Validated @RequestBody SysDictTypeBo dict) {
+        if (!dictTypeService.checkDictTypeUnique(dict)) {
+            return R.fail("鏂板瀛楀吀'" + dict.getDictName() + "'澶辫触锛屽瓧鍏哥被鍨嬪凡瀛樺湪");
+        }
+        dictTypeService.insertDictType(dict);
+        return R.ok();
+    }
+
+    /**
+     * 淇敼瀛楀吀绫诲瀷
+     */
+    @SaCheckPermission("system:dict:edit")
+    @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public R<Void> edit(@Validated @RequestBody SysDictTypeBo dict) {
+        if (!dictTypeService.checkDictTypeUnique(dict)) {
+            return R.fail("淇敼瀛楀吀'" + dict.getDictName() + "'澶辫触锛屽瓧鍏哥被鍨嬪凡瀛樺湪");
+        }
+        dictTypeService.updateDictType(dict);
+        return R.ok();
+    }
+
+    /**
+     * 鍒犻櫎瀛楀吀绫诲瀷
+     *
+     * @param dictIds 瀛楀吀ID涓�
+     */
+    @SaCheckPermission("system:dict:remove")
+    @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{dictIds}")
+    public R<Void> remove(@PathVariable Long[] dictIds) {
+        dictTypeService.deleteDictTypeByIds(dictIds);
+        return R.ok();
+    }
+
+    /**
+     * 鍒锋柊瀛楀吀缂撳瓨
+     */
+    @SaCheckPermission("system:dict:remove")
+    @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.CLEAN)
+    @DeleteMapping("/refreshCache")
+    public R<Void> refreshCache() {
+        dictTypeService.resetDictCache();
+        return R.ok();
+    }
+
+    /**
+     * 鑾峰彇瀛楀吀閫夋嫨妗嗗垪琛�
+     */
+    @GetMapping("/optionselect")
+    public R<List<SysDictTypeVo>> optionselect() {
+        List<SysDictTypeVo> dictTypes = dictTypeService.selectDictTypeAll();
+        return R.ok(dictTypes);
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysMenuController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysMenuController.java
new file mode 100644
index 0000000..c764839
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysMenuController.java
@@ -0,0 +1,182 @@
+package org.dromara.system.controller.system;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.dev33.satoken.annotation.SaCheckRole;
+import cn.dev33.satoken.annotation.SaMode;
+import cn.hutool.core.lang.tree.Tree;
+import org.dromara.common.core.constant.TenantConstants;
+import org.dromara.common.core.constant.UserConstants;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.system.domain.SysMenu;
+import org.dromara.system.domain.bo.SysMenuBo;
+import org.dromara.system.domain.vo.MenuTreeSelectVo;
+import org.dromara.system.domain.vo.RouterVo;
+import org.dromara.system.domain.vo.SysMenuVo;
+import org.dromara.system.service.ISysMenuService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 鑿滃崟淇℃伅
+ *
+ * @author Lion Li
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/system/menu")
+public class SysMenuController extends BaseController {
+
+    private final ISysMenuService menuService;
+
+    /**
+     * 鑾峰彇璺敱淇℃伅
+     *
+     * @return 璺敱淇℃伅
+     */
+    @GetMapping("/getRouters")
+    public R<List<RouterVo>> getRouters() {
+        List<SysMenu> menus = menuService.selectMenuTreeByUserId(LoginHelper.getUserId());
+        return R.ok(menuService.buildMenus(menus));
+    }
+
+    /**
+     * 鑾峰彇鑿滃崟鍒楄〃
+     */
+    @SaCheckRole(value = {
+            TenantConstants.SUPER_ADMIN_ROLE_KEY,
+            TenantConstants.TENANT_ADMIN_ROLE_KEY
+    }, mode = SaMode.OR)
+    @SaCheckPermission("system:menu:list")
+    @GetMapping("/list")
+    public R<List<SysMenuVo>> list(SysMenuBo menu) {
+        List<SysMenuVo> menus = menuService.selectMenuList(menu, LoginHelper.getUserId());
+        return R.ok(menus);
+    }
+
+    /**
+     * 鏍规嵁鑿滃崟缂栧彿鑾峰彇璇︾粏淇℃伅
+     *
+     * @param menuId 鑿滃崟ID
+     */
+    @SaCheckRole(value = {
+            TenantConstants.SUPER_ADMIN_ROLE_KEY,
+            TenantConstants.TENANT_ADMIN_ROLE_KEY
+    }, mode = SaMode.OR)
+    @SaCheckPermission("system:menu:query")
+    @GetMapping(value = "/{menuId}")
+    public R<SysMenuVo> getInfo(@PathVariable Long menuId) {
+        return R.ok(menuService.selectMenuById(menuId));
+    }
+
+    /**
+     * 鑾峰彇鑿滃崟涓嬫媺鏍戝垪琛�
+     */
+    @SaCheckRole(value = {
+            TenantConstants.SUPER_ADMIN_ROLE_KEY,
+            TenantConstants.TENANT_ADMIN_ROLE_KEY
+    }, mode = SaMode.OR)
+    @SaCheckPermission("system:menu:query")
+    @GetMapping("/treeselect")
+    public R<List<Tree<Long>>> treeselect(SysMenuBo menu) {
+        List<SysMenuVo> menus = menuService.selectMenuList(menu, LoginHelper.getUserId());
+        return R.ok(menuService.buildMenuTreeSelect(menus));
+    }
+
+    /**
+     * 鍔犺浇瀵瑰簲瑙掕壊鑿滃崟鍒楄〃鏍�
+     *
+     * @param roleId 瑙掕壊ID
+     */
+    @SaCheckRole(value = {
+            TenantConstants.SUPER_ADMIN_ROLE_KEY,
+            TenantConstants.TENANT_ADMIN_ROLE_KEY
+    }, mode = SaMode.OR)
+    @SaCheckPermission("system:menu:query")
+    @GetMapping(value = "/roleMenuTreeselect/{roleId}")
+    public R<MenuTreeSelectVo> roleMenuTreeselect(@PathVariable("roleId") Long roleId) {
+        List<SysMenuVo> menus = menuService.selectMenuList(LoginHelper.getUserId());
+        MenuTreeSelectVo selectVo = new MenuTreeSelectVo();
+        selectVo.setCheckedKeys(menuService.selectMenuListByRoleId(roleId));
+        selectVo.setMenus(menuService.buildMenuTreeSelect(menus));
+        return R.ok(selectVo);
+    }
+
+    /**
+     * 鍔犺浇瀵瑰簲绉熸埛濂楅鑿滃崟鍒楄〃鏍�
+     *
+     * @param packageId 绉熸埛濂楅ID
+     */
+    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckPermission("system:menu:query")
+    @GetMapping(value = "/tenantPackageMenuTreeselect/{packageId}")
+    public R<MenuTreeSelectVo> tenantPackageMenuTreeselect(@PathVariable("packageId") Long packageId) {
+        List<SysMenuVo> menus = menuService.selectMenuList(LoginHelper.getUserId());
+        MenuTreeSelectVo selectVo = new MenuTreeSelectVo();
+        selectVo.setCheckedKeys(menuService.selectMenuListByPackageId(packageId));
+        selectVo.setMenus(menuService.buildMenuTreeSelect(menus));
+        return R.ok(selectVo);
+    }
+
+    /**
+     * 鏂板鑿滃崟
+     */
+    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckPermission("system:menu:add")
+    @Log(title = "鑿滃崟绠$悊", businessType = BusinessType.INSERT)
+    @PostMapping
+    public R<Void> add(@Validated @RequestBody SysMenuBo menu) {
+        if (!menuService.checkMenuNameUnique(menu)) {
+            return R.fail("鏂板鑿滃崟'" + menu.getMenuName() + "'澶辫触锛岃彍鍗曞悕绉板凡瀛樺湪");
+        } else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) {
+            return R.fail("鏂板鑿滃崟'" + menu.getMenuName() + "'澶辫触锛屽湴鍧�蹇呴』浠ttp(s)://寮�澶�");
+        }
+        return toAjax(menuService.insertMenu(menu));
+    }
+
+    /**
+     * 淇敼鑿滃崟
+     */
+    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckPermission("system:menu:edit")
+    @Log(title = "鑿滃崟绠$悊", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public R<Void> edit(@Validated @RequestBody SysMenuBo menu) {
+        if (!menuService.checkMenuNameUnique(menu)) {
+            return R.fail("淇敼鑿滃崟'" + menu.getMenuName() + "'澶辫触锛岃彍鍗曞悕绉板凡瀛樺湪");
+        } else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) {
+            return R.fail("淇敼鑿滃崟'" + menu.getMenuName() + "'澶辫触锛屽湴鍧�蹇呴』浠ttp(s)://寮�澶�");
+        } else if (menu.getMenuId().equals(menu.getParentId())) {
+            return R.fail("淇敼鑿滃崟'" + menu.getMenuName() + "'澶辫触锛屼笂绾ц彍鍗曚笉鑳介�夋嫨鑷繁");
+        }
+        return toAjax(menuService.updateMenu(menu));
+    }
+
+    /**
+     * 鍒犻櫎鑿滃崟
+     *
+     * @param menuId 鑿滃崟ID
+     */
+    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckPermission("system:menu:remove")
+    @Log(title = "鑿滃崟绠$悊", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{menuId}")
+    public R<Void> remove(@PathVariable("menuId") Long menuId) {
+        if (menuService.hasChildByMenuId(menuId)) {
+            return R.warn("瀛樺湪瀛愯彍鍗�,涓嶅厑璁稿垹闄�");
+        }
+        if (menuService.checkMenuExistRole(menuId)) {
+            return R.warn("鑿滃崟宸插垎閰�,涓嶅厑璁稿垹闄�");
+        }
+        return toAjax(menuService.deleteMenuById(menuId));
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysNoticeController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysNoticeController.java
new file mode 100644
index 0000000..ce17ec7
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysNoticeController.java
@@ -0,0 +1,81 @@
+package org.dromara.system.controller.system;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.system.domain.bo.SysNoticeBo;
+import org.dromara.system.domain.vo.SysNoticeVo;
+import org.dromara.system.service.ISysNoticeService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 鍏憡 淇℃伅鎿嶄綔澶勭悊
+ *
+ * @author Lion Li
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/system/notice")
+public class SysNoticeController extends BaseController {
+
+    private final ISysNoticeService noticeService;
+
+    /**
+     * 鑾峰彇閫氱煡鍏憡鍒楄〃
+     */
+    @SaCheckPermission("system:notice:list")
+    @GetMapping("/list")
+    public TableDataInfo<SysNoticeVo> list(SysNoticeBo notice, PageQuery pageQuery) {
+        return noticeService.selectPageNoticeList(notice, pageQuery);
+    }
+
+    /**
+     * 鏍规嵁閫氱煡鍏憡缂栧彿鑾峰彇璇︾粏淇℃伅
+     *
+     * @param noticeId 鍏憡ID
+     */
+    @SaCheckPermission("system:notice:query")
+    @GetMapping(value = "/{noticeId}")
+    public R<SysNoticeVo> getInfo(@PathVariable Long noticeId) {
+        return R.ok(noticeService.selectNoticeById(noticeId));
+    }
+
+    /**
+     * 鏂板閫氱煡鍏憡
+     */
+    @SaCheckPermission("system:notice:add")
+    @Log(title = "閫氱煡鍏憡", businessType = BusinessType.INSERT)
+    @PostMapping
+    public R<Void> add(@Validated @RequestBody SysNoticeBo notice) {
+        return toAjax(noticeService.insertNotice(notice));
+    }
+
+    /**
+     * 淇敼閫氱煡鍏憡
+     */
+    @SaCheckPermission("system:notice:edit")
+    @Log(title = "閫氱煡鍏憡", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public R<Void> edit(@Validated @RequestBody SysNoticeBo notice) {
+        return toAjax(noticeService.updateNotice(notice));
+    }
+
+    /**
+     * 鍒犻櫎閫氱煡鍏憡
+     *
+     * @param noticeIds 鍏憡ID涓�
+     */
+    @SaCheckPermission("system:notice:remove")
+    @Log(title = "閫氱煡鍏憡", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{noticeIds}")
+    public R<Void> remove(@PathVariable Long[] noticeIds) {
+        return toAjax(noticeService.deleteNoticeByIds(noticeIds));
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysOssConfigController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysOssConfigController.java
new file mode 100644
index 0000000..45c93b8
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysOssConfigController.java
@@ -0,0 +1,105 @@
+package org.dromara.system.controller.system;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.core.validate.QueryGroup;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.system.domain.bo.SysOssConfigBo;
+import org.dromara.system.domain.vo.SysOssConfigVo;
+import org.dromara.system.service.ISysOssConfigService;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 瀵硅薄瀛樺偍閰嶇疆
+ *
+ * @author Lion Li
+ * @author 瀛よ垷鐑熼洦
+ * @date 2021-08-13
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/system/oss/config")
+public class SysOssConfigController extends BaseController {
+
+    private final ISysOssConfigService ossConfigService;
+
+    /**
+     * 鏌ヨ瀵硅薄瀛樺偍閰嶇疆鍒楄〃
+     */
+    @SaCheckPermission("system:oss:list")
+    @GetMapping("/list")
+    public TableDataInfo<SysOssConfigVo> list(@Validated(QueryGroup.class) SysOssConfigBo bo, PageQuery pageQuery) {
+        return ossConfigService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 鑾峰彇瀵硅薄瀛樺偍閰嶇疆璇︾粏淇℃伅
+     *
+     * @param ossConfigId OSS閰嶇疆ID
+     */
+    @SaCheckPermission("system:oss:query")
+    @GetMapping("/{ossConfigId}")
+    public R<SysOssConfigVo> getInfo(@NotNull(message = "涓婚敭涓嶈兘涓虹┖")
+                                     @PathVariable Long ossConfigId) {
+        return R.ok(ossConfigService.queryById(ossConfigId));
+    }
+
+    /**
+     * 鏂板瀵硅薄瀛樺偍閰嶇疆
+     */
+    @SaCheckPermission("system:oss:add")
+    @Log(title = "瀵硅薄瀛樺偍閰嶇疆", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody SysOssConfigBo bo) {
+        return toAjax(ossConfigService.insertByBo(bo));
+    }
+
+    /**
+     * 淇敼瀵硅薄瀛樺偍閰嶇疆
+     */
+    @SaCheckPermission("system:oss:edit")
+    @Log(title = "瀵硅薄瀛樺偍閰嶇疆", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysOssConfigBo bo) {
+        return toAjax(ossConfigService.updateByBo(bo));
+    }
+
+    /**
+     * 鍒犻櫎瀵硅薄瀛樺偍閰嶇疆
+     *
+     * @param ossConfigIds OSS閰嶇疆ID涓�
+     */
+    @SaCheckPermission("system:oss:remove")
+    @Log(title = "瀵硅薄瀛樺偍閰嶇疆", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ossConfigIds}")
+    public R<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
+                          @PathVariable Long[] ossConfigIds) {
+        return toAjax(ossConfigService.deleteWithValidByIds(List.of(ossConfigIds), true));
+    }
+
+    /**
+     * 鐘舵�佷慨鏀�
+     */
+    @SaCheckPermission("system:oss:edit")
+    @Log(title = "瀵硅薄瀛樺偍鐘舵�佷慨鏀�", businessType = BusinessType.UPDATE)
+    @PutMapping("/changeStatus")
+    public R<Void> changeStatus(@RequestBody SysOssConfigBo bo) {
+        return toAjax(ossConfigService.updateOssConfigStatus(bo));
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysOssController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysOssController.java
new file mode 100644
index 0000000..38096d0
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysOssController.java
@@ -0,0 +1,108 @@
+package org.dromara.system.controller.system;
+
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.hutool.core.util.ObjectUtil;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.QueryGroup;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.system.domain.bo.SysOssBo;
+import org.dromara.system.domain.vo.SysOssUploadVo;
+import org.dromara.system.domain.vo.SysOssVo;
+import org.dromara.system.service.ISysOssService;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.NotEmpty;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.MediaType;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 鏂囦欢涓婁紶 鎺у埗灞�
+ *
+ * @author Lion Li
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/system/oss")
+public class SysOssController extends BaseController {
+
+    private final ISysOssService ossService;
+
+    /**
+     * 鏌ヨOSS瀵硅薄瀛樺偍鍒楄〃
+     */
+    @SaCheckPermission("system:oss:list")
+    @GetMapping("/list")
+    public TableDataInfo<SysOssVo> list(@Validated(QueryGroup.class) SysOssBo bo, PageQuery pageQuery) {
+        return ossService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 鏌ヨOSS瀵硅薄鍩轰簬id涓�
+     *
+     * @param ossIds OSS瀵硅薄ID涓�
+     */
+    @SaCheckPermission("system:oss:list")
+    @GetMapping("/listByIds/{ossIds}")
+    public R<List<SysOssVo>> listByIds(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
+                                       @PathVariable Long[] ossIds) {
+        List<SysOssVo> list = ossService.listByIds(Arrays.asList(ossIds));
+        return R.ok(list);
+    }
+
+    /**
+     * 涓婁紶OSS瀵硅薄瀛樺偍
+     *
+     * @param file 鏂囦欢
+     */
+    @SaCheckPermission("system:oss:upload")
+    @Log(title = "OSS瀵硅薄瀛樺偍", businessType = BusinessType.INSERT)
+    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+    public R<SysOssUploadVo> upload(@RequestPart("file") MultipartFile file) {
+        if (ObjectUtil.isNull(file)) {
+            return R.fail("涓婁紶鏂囦欢涓嶈兘涓虹┖");
+        }
+        SysOssVo oss = ossService.upload(file);
+        SysOssUploadVo uploadVo = new SysOssUploadVo();
+        uploadVo.setUrl(oss.getUrl());
+        uploadVo.setFileName(oss.getOriginalName());
+        uploadVo.setOssId(oss.getOssId().toString());
+        return R.ok(uploadVo);
+    }
+
+    /**
+     * 涓嬭浇OSS瀵硅薄
+     *
+     * @param ossId OSS瀵硅薄ID
+     */
+    @SaCheckPermission("system:oss:download")
+    @GetMapping("/download/{ossId}")
+    public void download(@PathVariable Long ossId, HttpServletResponse response) throws IOException {
+        ossService.download(ossId, response);
+    }
+
+    /**
+     * 鍒犻櫎OSS瀵硅薄瀛樺偍
+     *
+     * @param ossIds OSS瀵硅薄ID涓�
+     */
+    @SaCheckPermission("system:oss:remove")
+    @Log(title = "OSS瀵硅薄瀛樺偍", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ossIds}")
+    public R<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
+                          @PathVariable Long[] ossIds) {
+        return toAjax(ossService.deleteWithValidByIds(List.of(ossIds), true));
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysPostController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysPostController.java
new file mode 100644
index 0000000..28e56a2
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysPostController.java
@@ -0,0 +1,115 @@
+package org.dromara.system.controller.system;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.system.domain.bo.SysPostBo;
+import org.dromara.system.domain.vo.SysPostVo;
+import org.dromara.system.service.ISysPostService;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 宀椾綅淇℃伅鎿嶄綔澶勭悊
+ *
+ * @author Lion Li
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/system/post")
+public class SysPostController extends BaseController {
+
+    private final ISysPostService postService;
+
+    /**
+     * 鑾峰彇宀椾綅鍒楄〃
+     */
+    @SaCheckPermission("system:post:list")
+    @GetMapping("/list")
+    public TableDataInfo<SysPostVo> list(SysPostBo post, PageQuery pageQuery) {
+        return postService.selectPagePostList(post, pageQuery);
+    }
+
+    /**
+     * 瀵煎嚭宀椾綅鍒楄〃
+     */
+    @Log(title = "宀椾綅绠$悊", businessType = BusinessType.EXPORT)
+    @SaCheckPermission("system:post:export")
+    @PostMapping("/export")
+    public void export(SysPostBo post, HttpServletResponse response) {
+        List<SysPostVo> list = postService.selectPostList(post);
+        ExcelUtil.exportExcel(list, "宀椾綅鏁版嵁", SysPostVo.class, response);
+    }
+
+    /**
+     * 鏍规嵁宀椾綅缂栧彿鑾峰彇璇︾粏淇℃伅
+     *
+     * @param postId 宀椾綅ID
+     */
+    @SaCheckPermission("system:post:query")
+    @GetMapping(value = "/{postId}")
+    public R<SysPostVo> getInfo(@PathVariable Long postId) {
+        return R.ok(postService.selectPostById(postId));
+    }
+
+    /**
+     * 鏂板宀椾綅
+     */
+    @SaCheckPermission("system:post:add")
+    @Log(title = "宀椾綅绠$悊", businessType = BusinessType.INSERT)
+    @PostMapping
+    public R<Void> add(@Validated @RequestBody SysPostBo post) {
+        if (!postService.checkPostNameUnique(post)) {
+            return R.fail("鏂板宀椾綅'" + post.getPostName() + "'澶辫触锛屽矖浣嶅悕绉板凡瀛樺湪");
+        } else if (!postService.checkPostCodeUnique(post)) {
+            return R.fail("鏂板宀椾綅'" + post.getPostName() + "'澶辫触锛屽矖浣嶇紪鐮佸凡瀛樺湪");
+        }
+        return toAjax(postService.insertPost(post));
+    }
+
+    /**
+     * 淇敼宀椾綅
+     */
+    @SaCheckPermission("system:post:edit")
+    @Log(title = "宀椾綅绠$悊", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public R<Void> edit(@Validated @RequestBody SysPostBo post) {
+        if (!postService.checkPostNameUnique(post)) {
+            return R.fail("淇敼宀椾綅'" + post.getPostName() + "'澶辫触锛屽矖浣嶅悕绉板凡瀛樺湪");
+        } else if (!postService.checkPostCodeUnique(post)) {
+            return R.fail("淇敼宀椾綅'" + post.getPostName() + "'澶辫触锛屽矖浣嶇紪鐮佸凡瀛樺湪");
+        }
+        return toAjax(postService.updatePost(post));
+    }
+
+    /**
+     * 鍒犻櫎宀椾綅
+     *
+     * @param postIds 宀椾綅ID涓�
+     */
+    @SaCheckPermission("system:post:remove")
+    @Log(title = "宀椾綅绠$悊", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{postIds}")
+    public R<Void> remove(@PathVariable Long[] postIds) {
+        return toAjax(postService.deletePostByIds(postIds));
+    }
+
+    /**
+     * 鑾峰彇宀椾綅閫夋嫨妗嗗垪琛�
+     */
+    @GetMapping("/optionselect")
+    public R<List<SysPostVo>> optionselect() {
+        List<SysPostVo> posts = postService.selectPostAll();
+        return R.ok(posts);
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java
new file mode 100644
index 0000000..60d1682
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java
@@ -0,0 +1,123 @@
+package org.dromara.system.controller.system;
+
+import cn.dev33.satoken.secure.BCrypt;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.io.FileUtil;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.core.utils.file.MimeTypeUtils;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.system.domain.bo.SysUserBo;
+import org.dromara.system.domain.bo.SysUserProfileBo;
+import org.dromara.system.domain.vo.AvatarVo;
+import org.dromara.system.domain.vo.ProfileVo;
+import org.dromara.system.domain.vo.SysOssVo;
+import org.dromara.system.domain.vo.SysUserVo;
+import org.dromara.system.service.ISysOssService;
+import org.dromara.system.service.ISysUserService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.MediaType;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.Arrays;
+
+/**
+ * 涓汉淇℃伅 涓氬姟澶勭悊
+ *
+ * @author Lion Li
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/system/user/profile")
+public class SysProfileController extends BaseController {
+
+    private final ISysUserService userService;
+    private final ISysOssService ossService;
+
+    /**
+     * 涓汉淇℃伅
+     */
+    @GetMapping
+    public R<ProfileVo> profile() {
+        SysUserVo user = userService.selectUserById(LoginHelper.getUserId());
+        ProfileVo profileVo = new ProfileVo();
+        profileVo.setUser(user);
+        profileVo.setRoleGroup(userService.selectUserRoleGroup(user.getUserName()));
+        profileVo.setPostGroup(userService.selectUserPostGroup(user.getUserName()));
+        return R.ok(profileVo);
+    }
+
+    /**
+     * 淇敼鐢ㄦ埛
+     */
+    @Log(title = "涓汉淇℃伅", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public R<Void> updateProfile(@RequestBody SysUserProfileBo profile) {
+        SysUserBo user = BeanUtil.toBean(profile, SysUserBo.class);
+        if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
+            return R.fail("淇敼鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛屾墜鏈哄彿鐮佸凡瀛樺湪");
+        }
+        if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
+            return R.fail("淇敼鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛岄偖绠辫处鍙峰凡瀛樺湪");
+        }
+        user.setUserId(LoginHelper.getUserId());
+        if (userService.updateUserProfile(user) > 0) {
+            return R.ok();
+        }
+        return R.fail("淇敼涓汉淇℃伅寮傚父锛岃鑱旂郴绠$悊鍛�");
+    }
+
+    /**
+     * 閲嶇疆瀵嗙爜
+     *
+     * @param newPassword 鏃у瘑鐮�
+     * @param oldPassword 鏂板瘑鐮�
+     */
+    @Log(title = "涓汉淇℃伅", businessType = BusinessType.UPDATE)
+    @PutMapping("/updatePwd")
+    public R<Void> updatePwd(String oldPassword, String newPassword) {
+        SysUserVo user = userService.selectUserById(LoginHelper.getUserId());
+        String password = user.getPassword();
+        if (!BCrypt.checkpw(oldPassword, password)) {
+            return R.fail("淇敼瀵嗙爜澶辫触锛屾棫瀵嗙爜閿欒");
+        }
+        if (BCrypt.checkpw(newPassword, password)) {
+            return R.fail("鏂板瘑鐮佷笉鑳戒笌鏃у瘑鐮佺浉鍚�");
+        }
+
+        if (userService.resetUserPwd(user.getUserId(), BCrypt.hashpw(newPassword)) > 0) {
+            return R.ok();
+        }
+        return R.fail("淇敼瀵嗙爜寮傚父锛岃鑱旂郴绠$悊鍛�");
+    }
+
+    /**
+     * 澶村儚涓婁紶
+     *
+     * @param avatarfile 鐢ㄦ埛澶村儚
+     */
+    @Log(title = "鐢ㄦ埛澶村儚", businessType = BusinessType.UPDATE)
+    @PostMapping(value = "/avatar", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+    public R<AvatarVo> avatar(@RequestPart("avatarfile") MultipartFile avatarfile) {
+        if (!avatarfile.isEmpty()) {
+            String extension = FileUtil.extName(avatarfile.getOriginalFilename());
+            if (!StringUtils.equalsAnyIgnoreCase(extension, MimeTypeUtils.IMAGE_EXTENSION)) {
+                return R.fail("鏂囦欢鏍煎紡涓嶆纭紝璇蜂笂浼�" + Arrays.toString(MimeTypeUtils.IMAGE_EXTENSION) + "鏍煎紡");
+            }
+            SysOssVo oss = ossService.upload(avatarfile);
+            String avatar = oss.getUrl();
+            if (userService.updateUserAvatar(LoginHelper.getUserId(), oss.getOssId())) {
+                AvatarVo avatarVo = new AvatarVo();
+                avatarVo.setImgUrl(avatar);
+                return R.ok(avatarVo);
+            }
+        }
+        return R.fail("涓婁紶鍥剧墖寮傚父锛岃鑱旂郴绠$悊鍛�");
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysRoleController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysRoleController.java
new file mode 100644
index 0000000..242fd9b
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysRoleController.java
@@ -0,0 +1,250 @@
+package org.dromara.system.controller.system;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.dev33.satoken.exception.NotLoginException;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.collection.CollUtil;
+import org.dromara.common.core.constant.GlobalConstants;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.domain.model.LoginUser;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.system.domain.SysUserRole;
+import org.dromara.system.domain.bo.SysDeptBo;
+import org.dromara.system.domain.bo.SysRoleBo;
+import org.dromara.system.domain.bo.SysUserBo;
+import org.dromara.system.domain.vo.DeptTreeSelectVo;
+import org.dromara.system.domain.vo.SysRoleVo;
+import org.dromara.system.domain.vo.SysUserVo;
+import org.dromara.system.service.ISysDeptService;
+import org.dromara.system.service.ISysRoleService;
+import org.dromara.system.service.ISysUserService;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 瑙掕壊淇℃伅
+ *
+ * @author Lion Li
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/system/role")
+public class SysRoleController extends BaseController {
+
+    private final ISysRoleService roleService;
+    private final ISysUserService userService;
+    private final ISysDeptService deptService;
+
+    /**
+     * 鑾峰彇瑙掕壊淇℃伅鍒楄〃
+     */
+    @SaCheckPermission("system:role:list")
+    @GetMapping("/list")
+    public TableDataInfo<SysRoleVo> list(SysRoleBo role, PageQuery pageQuery) {
+        return roleService.selectPageRoleList(role, pageQuery);
+    }
+
+    /**
+     * 瀵煎嚭瑙掕壊淇℃伅鍒楄〃
+     */
+    @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.EXPORT)
+    @SaCheckPermission("system:role:export")
+    @PostMapping("/export")
+    public void export(SysRoleBo role, HttpServletResponse response) {
+        List<SysRoleVo> list = roleService.selectRoleList(role);
+        ExcelUtil.exportExcel(list, "瑙掕壊鏁版嵁", SysRoleVo.class, response);
+    }
+
+    /**
+     * 鏍规嵁瑙掕壊缂栧彿鑾峰彇璇︾粏淇℃伅
+     *
+     * @param roleId 瑙掕壊ID
+     */
+    @SaCheckPermission("system:role:query")
+    @GetMapping(value = "/{roleId}")
+    public R<SysRoleVo> getInfo(@PathVariable Long roleId) {
+        roleService.checkRoleDataScope(roleId);
+        return R.ok(roleService.selectRoleById(roleId));
+    }
+
+    /**
+     * 鏂板瑙掕壊
+     */
+    @SaCheckPermission("system:role:add")
+    @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.INSERT)
+    @PostMapping
+    public R<Void> add(@Validated @RequestBody SysRoleBo role) {
+        if (!roleService.checkRoleNameUnique(role)) {
+            return R.fail("鏂板瑙掕壊'" + role.getRoleName() + "'澶辫触锛岃鑹插悕绉板凡瀛樺湪");
+        } else if (!roleService.checkRoleKeyUnique(role)) {
+            return R.fail("鏂板瑙掕壊'" + role.getRoleName() + "'澶辫触锛岃鑹叉潈闄愬凡瀛樺湪");
+        }
+        return toAjax(roleService.insertRole(role));
+
+    }
+
+    /**
+     * 淇敼淇濆瓨瑙掕壊
+     */
+    @SaCheckPermission("system:role:edit")
+    @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public R<Void> edit(@Validated @RequestBody SysRoleBo role) {
+        roleService.checkRoleAllowed(role.getRoleId());
+        roleService.checkRoleDataScope(role.getRoleId());
+        if (!roleService.checkRoleNameUnique(role)) {
+            return R.fail("淇敼瑙掕壊'" + role.getRoleName() + "'澶辫触锛岃鑹插悕绉板凡瀛樺湪");
+        } else if (!roleService.checkRoleKeyUnique(role)) {
+            return R.fail("淇敼瑙掕壊'" + role.getRoleName() + "'澶辫触锛岃鑹叉潈闄愬凡瀛樺湪");
+        }
+
+        if (roleService.updateRole(role) > 0) {
+            List<String> keys = StpUtil.searchTokenValue("", 0, -1, false);
+            if (CollUtil.isEmpty(keys)) {
+                return R.ok();
+            }
+            // 瑙掕壊鍏宠仈鐨勫湪绾跨敤鎴烽噺杩囧ぇ浼氬鑷磖edis闃诲鍗¢】 璋ㄦ厧鎿嶄綔
+            keys.parallelStream().forEach(key -> {
+                String token = key.replace(GlobalConstants.LOGIN_TOKEN_KEY, "");
+                // 濡傛灉宸茬粡杩囨湡鍒欒烦杩�
+                if (StpUtil.stpLogic.getTokenActivityTimeoutByToken(token) < -1) {
+                    return;
+                }
+                LoginUser loginUser = LoginHelper.getLoginUser(token);
+                if (loginUser.getRoles().stream().anyMatch(r -> r.getRoleId().equals(role.getRoleId()))) {
+                    try {
+                        StpUtil.logoutByTokenValue(token);
+                    } catch (NotLoginException ignored) {
+                    }
+                }
+            });
+            return R.ok();
+        }
+        return R.fail("淇敼瑙掕壊'" + role.getRoleName() + "'澶辫触锛岃鑱旂郴绠$悊鍛�");
+    }
+
+    /**
+     * 淇敼淇濆瓨鏁版嵁鏉冮檺
+     */
+    @SaCheckPermission("system:role:edit")
+    @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.UPDATE)
+    @PutMapping("/dataScope")
+    public R<Void> dataScope(@RequestBody SysRoleBo role) {
+        roleService.checkRoleAllowed(role.getRoleId());
+        roleService.checkRoleDataScope(role.getRoleId());
+        return toAjax(roleService.authDataScope(role));
+    }
+
+    /**
+     * 鐘舵�佷慨鏀�
+     */
+    @SaCheckPermission("system:role:edit")
+    @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.UPDATE)
+    @PutMapping("/changeStatus")
+    public R<Void> changeStatus(@RequestBody SysRoleBo role) {
+        roleService.checkRoleAllowed(role.getRoleId());
+        roleService.checkRoleDataScope(role.getRoleId());
+        return toAjax(roleService.updateRoleStatus(role.getRoleId(), role.getStatus()));
+    }
+
+    /**
+     * 鍒犻櫎瑙掕壊
+     *
+     * @param roleIds 瑙掕壊ID涓�
+     */
+    @SaCheckPermission("system:role:remove")
+    @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{roleIds}")
+    public R<Void> remove(@PathVariable Long[] roleIds) {
+        return toAjax(roleService.deleteRoleByIds(roleIds));
+    }
+
+    /**
+     * 鑾峰彇瑙掕壊閫夋嫨妗嗗垪琛�
+     */
+    @SaCheckPermission("system:role:query")
+    @GetMapping("/optionselect")
+    public R<List<SysRoleVo>> optionselect() {
+        return R.ok(roleService.selectRoleAll());
+    }
+
+    /**
+     * 鏌ヨ宸插垎閰嶇敤鎴疯鑹插垪琛�
+     */
+    @SaCheckPermission("system:role:list")
+    @GetMapping("/authUser/allocatedList")
+    public TableDataInfo<SysUserVo> allocatedList(SysUserBo user, PageQuery pageQuery) {
+        return userService.selectAllocatedList(user, pageQuery);
+    }
+
+    /**
+     * 鏌ヨ鏈垎閰嶇敤鎴疯鑹插垪琛�
+     */
+    @SaCheckPermission("system:role:list")
+    @GetMapping("/authUser/unallocatedList")
+    public TableDataInfo<SysUserVo> unallocatedList(SysUserBo user, PageQuery pageQuery) {
+        return userService.selectUnallocatedList(user, pageQuery);
+    }
+
+    /**
+     * 鍙栨秷鎺堟潈鐢ㄦ埛
+     */
+    @SaCheckPermission("system:role:edit")
+    @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.GRANT)
+    @PutMapping("/authUser/cancel")
+    public R<Void> cancelAuthUser(@RequestBody SysUserRole userRole) {
+        return toAjax(roleService.deleteAuthUser(userRole));
+    }
+
+    /**
+     * 鎵归噺鍙栨秷鎺堟潈鐢ㄦ埛
+     *
+     * @param roleId  瑙掕壊ID
+     * @param userIds 鐢ㄦ埛ID涓�
+     */
+    @SaCheckPermission("system:role:edit")
+    @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.GRANT)
+    @PutMapping("/authUser/cancelAll")
+    public R<Void> cancelAuthUserAll(Long roleId, Long[] userIds) {
+        return toAjax(roleService.deleteAuthUsers(roleId, userIds));
+    }
+
+    /**
+     * 鎵归噺閫夋嫨鐢ㄦ埛鎺堟潈
+     *
+     * @param roleId  瑙掕壊ID
+     * @param userIds 鐢ㄦ埛ID涓�
+     */
+    @SaCheckPermission("system:role:edit")
+    @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.GRANT)
+    @PutMapping("/authUser/selectAll")
+    public R<Void> selectAuthUserAll(Long roleId, Long[] userIds) {
+        roleService.checkRoleDataScope(roleId);
+        return toAjax(roleService.insertAuthUsers(roleId, userIds));
+    }
+
+    /**
+     * 鑾峰彇瀵瑰簲瑙掕壊閮ㄩ棬鏍戝垪琛�
+     *
+     * @param roleId 瑙掕壊ID
+     */
+    @SaCheckPermission("system:role:list")
+    @GetMapping(value = "/deptTree/{roleId}")
+    public R<DeptTreeSelectVo> roleDeptTreeselect(@PathVariable("roleId") Long roleId) {
+        DeptTreeSelectVo selectVo = new DeptTreeSelectVo();
+        selectVo.setCheckedKeys(deptService.selectDeptListByRoleId(roleId));
+        selectVo.setDepts(deptService.selectDeptTreeList(new SysDeptBo()));
+        return R.ok(selectVo);
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java
new file mode 100644
index 0000000..4ef666d
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java
@@ -0,0 +1,174 @@
+package org.dromara.system.controller.system;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.dev33.satoken.annotation.SaCheckRole;
+import com.baomidou.lock.annotation.Lock4j;
+import org.dromara.common.core.constant.TenantConstants;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.tenant.helper.TenantHelper;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.system.domain.bo.SysTenantBo;
+import org.dromara.system.domain.vo.SysTenantVo;
+import org.dromara.system.service.ISysTenantService;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 绉熸埛绠$悊
+ *
+ * @author Michelle.Chung
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/system/tenant")
+public class SysTenantController extends BaseController {
+
+    private final ISysTenantService tenantService;
+
+    /**
+     * 鏌ヨ绉熸埛鍒楄〃
+     */
+    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckPermission("system:tenant:list")
+    @GetMapping("/list")
+    public TableDataInfo<SysTenantVo> list(SysTenantBo bo, PageQuery pageQuery) {
+        return tenantService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 瀵煎嚭绉熸埛鍒楄〃
+     */
+    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckPermission("system:tenant:export")
+    @Log(title = "绉熸埛", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(SysTenantBo bo, HttpServletResponse response) {
+        List<SysTenantVo> list = tenantService.queryList(bo);
+        ExcelUtil.exportExcel(list, "绉熸埛", SysTenantVo.class, response);
+    }
+
+    /**
+     * 鑾峰彇绉熸埛璇︾粏淇℃伅
+     *
+     * @param id 涓婚敭
+     */
+    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckPermission("system:tenant:query")
+    @GetMapping("/{id}")
+    public R<SysTenantVo> getInfo(@NotNull(message = "涓婚敭涓嶈兘涓虹┖")
+                                     @PathVariable Long id) {
+        return R.ok(tenantService.queryById(id));
+    }
+
+    /**
+     * 鏂板绉熸埛
+     */
+    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckPermission("system:tenant:add")
+    @Log(title = "绉熸埛", businessType = BusinessType.INSERT)
+    @Lock4j
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody SysTenantBo bo) {
+        if (!tenantService.checkCompanyNameUnique(bo)) {
+            return R.fail("鏂板绉熸埛'" + bo.getCompanyName() + "'澶辫触锛屼紒涓氬悕绉板凡瀛樺湪");
+        }
+        return toAjax(tenantService.insertByBo(bo));
+    }
+
+    /**
+     * 淇敼绉熸埛
+     */
+    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckPermission("system:tenant:edit")
+    @Log(title = "绉熸埛", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysTenantBo bo) {
+        tenantService.checkTenantAllowed(bo.getTenantId());
+        if (!tenantService.checkCompanyNameUnique(bo)) {
+            return R.fail("淇敼绉熸埛'" + bo.getCompanyName() + "'澶辫触锛屽叕鍙稿悕绉板凡瀛樺湪");
+        }
+        return toAjax(tenantService.updateByBo(bo));
+    }
+
+    /**
+     * 鐘舵�佷慨鏀�
+     */
+    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckPermission("system:tenant:edit")
+    @Log(title = "绉熸埛", businessType = BusinessType.UPDATE)
+    @PutMapping("/changeStatus")
+    public R<Void> changeStatus(@RequestBody SysTenantBo bo) {
+        tenantService.checkTenantAllowed(bo.getTenantId());
+        return toAjax(tenantService.updateTenantStatus(bo));
+    }
+
+    /**
+     * 鍒犻櫎绉熸埛
+     *
+     * @param ids 涓婚敭涓�
+     */
+    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckPermission("system:tenant:remove")
+    @Log(title = "绉熸埛", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
+                          @PathVariable Long[] ids) {
+        return toAjax(tenantService.deleteWithValidByIds(List.of(ids), true));
+    }
+
+    /**
+     * 鍔ㄦ�佸垏鎹㈢鎴�
+     *
+     * @param tenantId 绉熸埛ID
+     */
+    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @GetMapping("/dynamic/{tenantId}")
+    public R<Void> dynamicTenant(@NotBlank(message = "绉熸埛ID涓嶈兘涓虹┖") @PathVariable String tenantId) {
+        TenantHelper.setDynamic(tenantId);
+        return R.ok();
+    }
+
+    /**
+     * 娓呴櫎鍔ㄦ�佺鎴�
+     */
+    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @GetMapping("/dynamic/clear")
+    public R<Void> dynamicClear() {
+        TenantHelper.clearDynamic();
+        return R.ok();
+    }
+
+
+    /**
+     * 鍚屾绉熸埛濂楅
+     *
+     * @param tenantId  绉熸埛id
+     * @param packageId 濂楅id
+     */
+    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckPermission("system:tenant:edit")
+    @Log(title = "绉熸埛", businessType = BusinessType.UPDATE)
+    @GetMapping("/syncTenantPackage")
+    public R<Void> syncTenantPackage(@NotBlank(message = "绉熸埛ID涓嶈兘涓虹┖") String tenantId, @NotBlank(message = "濂楅ID涓嶈兘涓虹┖") String packageId) {
+        return toAjax(tenantService.syncTenantPackage(tenantId, packageId));
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantPackageController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantPackageController.java
new file mode 100644
index 0000000..0172176
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantPackageController.java
@@ -0,0 +1,124 @@
+package org.dromara.system.controller.system;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.dev33.satoken.annotation.SaCheckRole;
+import org.dromara.common.core.constant.TenantConstants;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.system.domain.bo.SysTenantPackageBo;
+import org.dromara.system.domain.vo.SysTenantPackageVo;
+import org.dromara.system.service.ISysTenantPackageService;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 绉熸埛濂楅绠$悊
+ *
+ * @author Michelle.Chung
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/system/tenant/package")
+public class SysTenantPackageController extends BaseController {
+
+    private final ISysTenantPackageService tenantPackageService;
+
+    /**
+     * 鏌ヨ绉熸埛濂楅鍒楄〃
+     */
+    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckPermission("system:tenantPackage:list")
+    @GetMapping("/list")
+    public TableDataInfo<SysTenantPackageVo> list(SysTenantPackageBo bo, PageQuery pageQuery) {
+        return tenantPackageService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 瀵煎嚭绉熸埛濂楅鍒楄〃
+     */
+    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckPermission("system:tenantPackage:export")
+    @Log(title = "绉熸埛濂楅", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(SysTenantPackageBo bo, HttpServletResponse response) {
+        List<SysTenantPackageVo> list = tenantPackageService.queryList(bo);
+        ExcelUtil.exportExcel(list, "绉熸埛濂楅", SysTenantPackageVo.class, response);
+    }
+
+    /**
+     * 鑾峰彇绉熸埛濂楅璇︾粏淇℃伅
+     *
+     * @param packageId 涓婚敭
+     */
+    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckPermission("system:tenantPackage:query")
+    @GetMapping("/{packageId}")
+    public R<SysTenantPackageVo> getInfo(@NotNull(message = "涓婚敭涓嶈兘涓虹┖")
+                                     @PathVariable Long packageId) {
+        return R.ok(tenantPackageService.queryById(packageId));
+    }
+
+    /**
+     * 鏂板绉熸埛濂楅
+     */
+    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckPermission("system:tenantPackage:add")
+    @Log(title = "绉熸埛濂楅", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody SysTenantPackageBo bo) {
+        return toAjax(tenantPackageService.insertByBo(bo));
+    }
+
+    /**
+     * 淇敼绉熸埛濂楅
+     */
+    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckPermission("system:tenantPackage:edit")
+    @Log(title = "绉熸埛濂楅", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysTenantPackageBo bo) {
+        return toAjax(tenantPackageService.updateByBo(bo));
+    }
+
+    /**
+     * 鐘舵�佷慨鏀�
+     */
+    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckPermission("system:tenantPackage:edit")
+    @Log(title = "绉熸埛濂楅", businessType = BusinessType.UPDATE)
+    @PutMapping("/changeStatus")
+    public R<Void> changeStatus(@RequestBody SysTenantPackageBo bo) {
+        return toAjax(tenantPackageService.updatePackageStatus(bo));
+    }
+
+    /**
+     * 鍒犻櫎绉熸埛濂楅
+     *
+     * @param packageIds 涓婚敭涓�
+     */
+    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckPermission("system:tenantPackage:remove")
+    @Log(title = "绉熸埛濂楅", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{packageIds}")
+    public R<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
+                          @PathVariable Long[] packageIds) {
+        return toAjax(tenantPackageService.deleteWithValidByIds(List.of(packageIds), true));
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java
new file mode 100644
index 0000000..eef0a1a
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java
@@ -0,0 +1,261 @@
+package org.dromara.system.controller.system;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.dev33.satoken.secure.BCrypt;
+import cn.hutool.core.lang.tree.Tree;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.ObjectUtil;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.domain.model.LoginUser;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StreamUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.excel.core.ExcelResult;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.common.tenant.helper.TenantHelper;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.system.domain.bo.SysDeptBo;
+import org.dromara.system.domain.bo.SysUserBo;
+import org.dromara.system.domain.vo.*;
+import org.dromara.system.listener.SysUserImportListener;
+import org.dromara.system.service.*;
+import org.springframework.http.MediaType;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 鐢ㄦ埛淇℃伅
+ *
+ * @author Lion Li
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/system/user")
+public class SysUserController extends BaseController {
+
+    private final ISysUserService userService;
+    private final ISysRoleService roleService;
+    private final ISysPostService postService;
+    private final ISysDeptService deptService;
+    private final ISysTenantService tenantService;
+
+    /**
+     * 鑾峰彇鐢ㄦ埛鍒楄〃
+     */
+    @SaCheckPermission("system:user:list")
+    @GetMapping("/list")
+    public TableDataInfo<SysUserVo> list(SysUserBo user, PageQuery pageQuery) {
+        return userService.selectPageUserList(user, pageQuery);
+    }
+
+    /**
+     * 瀵煎嚭鐢ㄦ埛鍒楄〃
+     */
+    @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.EXPORT)
+    @SaCheckPermission("system:user:export")
+    @PostMapping("/export")
+    public void export(SysUserBo user, HttpServletResponse response) {
+        List<SysUserVo> list = userService.selectUserList(user);
+        List<SysUserExportVo> listVo = MapstructUtils.convert(list, SysUserExportVo.class);
+        ExcelUtil.exportExcel(listVo, "鐢ㄦ埛鏁版嵁", SysUserExportVo.class, response);
+    }
+
+    /**
+     * 瀵煎叆鏁版嵁
+     *
+     * @param file          瀵煎叆鏂囦欢
+     * @param updateSupport 鏄惁鏇存柊宸插瓨鍦ㄦ暟鎹�
+     */
+    @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.IMPORT)
+    @SaCheckPermission("system:user:import")
+    @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+    public R<Void> importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception {
+        ExcelResult<SysUserImportVo> result = ExcelUtil.importExcel(file.getInputStream(), SysUserImportVo.class, new SysUserImportListener(updateSupport));
+        return R.ok(result.getAnalysis());
+    }
+
+    /**
+     * 鑾峰彇瀵煎叆妯℃澘
+     */
+    @PostMapping("/importTemplate")
+    public void importTemplate(HttpServletResponse response) {
+        ExcelUtil.exportExcel(new ArrayList<>(), "鐢ㄦ埛鏁版嵁", SysUserImportVo.class, response);
+    }
+
+    /**
+     * 鑾峰彇鐢ㄦ埛淇℃伅
+     *
+     * @return 鐢ㄦ埛淇℃伅
+     */
+    @GetMapping("/getInfo")
+    public R<UserInfoVo> getInfo() {
+        UserInfoVo userInfoVo = new UserInfoVo();
+        LoginUser loginUser = LoginHelper.getLoginUser();
+        if (TenantHelper.isEnable() && LoginHelper.isSuperAdmin()) {
+            // 瓒呯骇绠$悊鍛� 濡傛灉閲嶆柊鍔犺浇鐢ㄦ埛淇℃伅闇�娓呴櫎鍔ㄦ�佺鎴�
+            TenantHelper.clearDynamic();
+        }
+        SysUserVo user = userService.selectUserById(loginUser.getUserId());
+        userInfoVo.setUser(user);
+        userInfoVo.setPermissions(loginUser.getMenuPermission());
+        userInfoVo.setRoles(loginUser.getRolePermission());
+        return R.ok(userInfoVo);
+    }
+
+    /**
+     * 鏍规嵁鐢ㄦ埛缂栧彿鑾峰彇璇︾粏淇℃伅
+     *
+     * @param userId 鐢ㄦ埛ID
+     */
+    @SaCheckPermission("system:user:query")
+    @GetMapping(value = {"/", "/{userId}"})
+    public R<SysUserInfoVo> getInfo(@PathVariable(value = "userId", required = false) Long userId) {
+        userService.checkUserDataScope(userId);
+        SysUserInfoVo userInfoVo = new SysUserInfoVo();
+        List<SysRoleVo> roles = roleService.selectRoleAll();
+        userInfoVo.setRoles(LoginHelper.isSuperAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isSuperAdmin()));
+        userInfoVo.setPosts(postService.selectPostAll());
+        if (ObjectUtil.isNotNull(userId)) {
+            SysUserVo sysUser = userService.selectUserById(userId);
+            userInfoVo.setUser(sysUser);
+            userInfoVo.setRoleIds(StreamUtils.toList(sysUser.getRoles(), SysRoleVo::getRoleId));
+            userInfoVo.setPostIds(postService.selectPostListByUserId(userId));
+        }
+        return R.ok(userInfoVo);
+    }
+
+    /**
+     * 鏂板鐢ㄦ埛
+     */
+    @SaCheckPermission("system:user:add")
+    @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.INSERT)
+    @PostMapping
+    public R<Void> add(@Validated @RequestBody SysUserBo user) {
+        if (!userService.checkUserNameUnique(user)) {
+            return R.fail("鏂板鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛岀櫥褰曡处鍙峰凡瀛樺湪");
+        } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
+            return R.fail("鏂板鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛屾墜鏈哄彿鐮佸凡瀛樺湪");
+        } else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
+            return R.fail("鏂板鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛岄偖绠辫处鍙峰凡瀛樺湪");
+        }
+        if (TenantHelper.isEnable()) {
+            if (!tenantService.checkAccountBalance(TenantHelper.getTenantId())) {
+                return R.fail("褰撳墠绉熸埛涓嬬敤鎴峰悕棰濅笉瓒筹紝璇疯仈绯荤鐞嗗憳");
+            }
+        }
+        user.setPassword(BCrypt.hashpw(user.getPassword()));
+        return toAjax(userService.insertUser(user));
+    }
+
+    /**
+     * 淇敼鐢ㄦ埛
+     */
+    @SaCheckPermission("system:user:edit")
+    @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public R<Void> edit(@Validated @RequestBody SysUserBo user) {
+        userService.checkUserAllowed(user.getUserId());
+        userService.checkUserDataScope(user.getUserId());
+        if (!userService.checkUserNameUnique(user)) {
+            return R.fail("淇敼鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛岀櫥褰曡处鍙峰凡瀛樺湪");
+        } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
+            return R.fail("淇敼鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛屾墜鏈哄彿鐮佸凡瀛樺湪");
+        } else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
+            return R.fail("淇敼鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛岄偖绠辫处鍙峰凡瀛樺湪");
+        }
+        return toAjax(userService.updateUser(user));
+    }
+
+    /**
+     * 鍒犻櫎鐢ㄦ埛
+     *
+     * @param userIds 瑙掕壊ID涓�
+     */
+    @SaCheckPermission("system:user:remove")
+    @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{userIds}")
+    public R<Void> remove(@PathVariable Long[] userIds) {
+        if (ArrayUtil.contains(userIds, LoginHelper.getUserId())) {
+            return R.fail("褰撳墠鐢ㄦ埛涓嶈兘鍒犻櫎");
+        }
+        return toAjax(userService.deleteUserByIds(userIds));
+    }
+
+    /**
+     * 閲嶇疆瀵嗙爜
+     */
+    @SaCheckPermission("system:user:resetPwd")
+    @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.UPDATE)
+    @PutMapping("/resetPwd")
+    public R<Void> resetPwd(@RequestBody SysUserBo user) {
+        userService.checkUserAllowed(user.getUserId());
+        userService.checkUserDataScope(user.getUserId());
+        user.setPassword(BCrypt.hashpw(user.getPassword()));
+        return toAjax(userService.resetUserPwd(user.getUserId(), user.getPassword()));
+    }
+
+    /**
+     * 鐘舵�佷慨鏀�
+     */
+    @SaCheckPermission("system:user:edit")
+    @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.UPDATE)
+    @PutMapping("/changeStatus")
+    public R<Void> changeStatus(@RequestBody SysUserBo user) {
+        userService.checkUserAllowed(user.getUserId());
+        userService.checkUserDataScope(user.getUserId());
+        return toAjax(userService.updateUserStatus(user.getUserId(), user.getStatus()));
+    }
+
+    /**
+     * 鏍规嵁鐢ㄦ埛缂栧彿鑾峰彇鎺堟潈瑙掕壊
+     *
+     * @param userId 鐢ㄦ埛ID
+     */
+    @SaCheckPermission("system:user:query")
+    @GetMapping("/authRole/{userId}")
+    public R<SysUserInfoVo> authRole(@PathVariable Long userId) {
+        SysUserVo user = userService.selectUserById(userId);
+        List<SysRoleVo> roles = roleService.selectRolesByUserId(userId);
+        SysUserInfoVo userInfoVo = new SysUserInfoVo();
+        userInfoVo.setUser(user);
+        userInfoVo.setRoles(LoginHelper.isSuperAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isSuperAdmin()));
+        return R.ok(userInfoVo);
+    }
+
+    /**
+     * 鐢ㄦ埛鎺堟潈瑙掕壊
+     *
+     * @param userId  鐢ㄦ埛Id
+     * @param roleIds 瑙掕壊ID涓�
+     */
+    @SaCheckPermission("system:user:edit")
+    @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.GRANT)
+    @PutMapping("/authRole")
+    public R<Void> insertAuthRole(Long userId, Long[] roleIds) {
+        userService.checkUserDataScope(userId);
+        userService.insertUserAuth(userId, roleIds);
+        return R.ok();
+    }
+
+    /**
+     * 鑾峰彇閮ㄩ棬鏍戝垪琛�
+     */
+    @SaCheckPermission("system:user:list")
+    @GetMapping("/deptTree")
+    public R<List<Tree<Long>>> deptTree(SysDeptBo dept) {
+        return R.ok(deptService.selectDeptTreeList(dept));
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysCache.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysCache.java
new file mode 100644
index 0000000..e398a20
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysCache.java
@@ -0,0 +1,47 @@
+package org.dromara.system.domain;
+
+import org.dromara.common.core.utils.StringUtils;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 缂撳瓨淇℃伅
+ *
+ * @author Lion Li
+ */
+@Data
+@NoArgsConstructor
+public class SysCache {
+
+    /**
+     * 缂撳瓨鍚嶇О
+     */
+    private String cacheName = "";
+
+    /**
+     * 缂撳瓨閿悕
+     */
+    private String cacheKey = "";
+
+    /**
+     * 缂撳瓨鍐呭
+     */
+    private String cacheValue = "";
+
+    /**
+     * 澶囨敞
+     */
+    private String remark = "";
+
+    public SysCache(String cacheName, String remark) {
+        this.cacheName = cacheName;
+        this.remark = remark;
+    }
+
+    public SysCache(String cacheName, String cacheKey, String cacheValue) {
+        this.cacheName = StringUtils.replace(cacheName, ":", "");
+        this.cacheKey = StringUtils.replace(cacheKey, cacheName, "");
+        this.cacheValue = cacheValue;
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysConfig.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysConfig.java
new file mode 100644
index 0000000..6fcb88f
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysConfig.java
@@ -0,0 +1,51 @@
+package org.dromara.system.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import org.dromara.common.tenant.core.TenantEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 鍙傛暟閰嶇疆琛� sys_config
+ *
+ * @author Lion Li
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("sys_config")
+public class SysConfig extends TenantEntity {
+
+    /**
+     * 鍙傛暟涓婚敭
+     */
+    @TableId(value = "config_id")
+    private Long configId;
+
+    /**
+     * 鍙傛暟鍚嶇О
+     */
+    private String configName;
+
+    /**
+     * 鍙傛暟閿悕
+     */
+    private String configKey;
+
+    /**
+     * 鍙傛暟閿��
+     */
+    private String configValue;
+
+    /**
+     * 绯荤粺鍐呯疆锛圷鏄� N鍚︼級
+     */
+    private String configType;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysDept.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysDept.java
new file mode 100644
index 0000000..d7ad7c4
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysDept.java
@@ -0,0 +1,78 @@
+package org.dromara.system.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import org.dromara.common.tenant.core.TenantEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 閮ㄩ棬琛� sys_dept
+ *
+ * @author Lion Li
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("sys_dept")
+public class SysDept extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 閮ㄩ棬ID
+     */
+    @TableId(value = "dept_id")
+    private Long deptId;
+
+    /**
+     * 鐖堕儴闂↖D
+     */
+    private Long parentId;
+
+    /**
+     * 閮ㄩ棬鍚嶇О
+     */
+    private String deptName;
+
+    /**
+     * 鏄剧ず椤哄簭
+     */
+    private Integer orderNum;
+
+    /**
+     * 璐熻矗浜�
+     */
+    private String leader;
+
+    /**
+     * 鑱旂郴鐢佃瘽
+     */
+    private String phone;
+
+    /**
+     * 閭
+     */
+    private String email;
+
+    /**
+     * 閮ㄩ棬鐘舵��:0姝e父,1鍋滅敤
+     */
+    private String status;
+
+    /**
+     * 鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛�
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 绁栫骇鍒楄〃
+     */
+    private String ancestors;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysDictData.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysDictData.java
new file mode 100644
index 0000000..9b60d92
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysDictData.java
@@ -0,0 +1,76 @@
+package org.dromara.system.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import org.dromara.common.core.constant.UserConstants;
+import org.dromara.common.tenant.core.TenantEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 瀛楀吀鏁版嵁琛� sys_dict_data
+ *
+ * @author Lion Li
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("sys_dict_data")
+public class SysDictData extends TenantEntity {
+
+    /**
+     * 瀛楀吀缂栫爜
+     */
+    @TableId(value = "dict_code")
+    private Long dictCode;
+
+    /**
+     * 瀛楀吀鎺掑簭
+     */
+    private Integer dictSort;
+
+    /**
+     * 瀛楀吀鏍囩
+     */
+    private String dictLabel;
+
+    /**
+     * 瀛楀吀閿��
+     */
+    private String dictValue;
+
+    /**
+     * 瀛楀吀绫诲瀷
+     */
+    private String dictType;
+
+    /**
+     * 鏍峰紡灞炴�э紙鍏朵粬鏍峰紡鎵╁睍锛�
+     */
+    private String cssClass;
+
+    /**
+     * 琛ㄦ牸瀛楀吀鏍峰紡
+     */
+    private String listClass;
+
+    /**
+     * 鏄惁榛樿锛圷鏄� N鍚︼級
+     */
+    private String isDefault;
+
+    /**
+     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    private String status;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+    public boolean getDefault() {
+        return UserConstants.YES.equals(this.isDefault);
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysDictType.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysDictType.java
new file mode 100644
index 0000000..5345f87
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysDictType.java
@@ -0,0 +1,46 @@
+package org.dromara.system.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import org.dromara.common.tenant.core.TenantEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 瀛楀吀绫诲瀷琛� sys_dict_type
+ *
+ * @author Lion Li
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("sys_dict_type")
+public class SysDictType extends TenantEntity {
+
+    /**
+     * 瀛楀吀涓婚敭
+     */
+    @TableId(value = "dict_id")
+    private Long dictId;
+
+    /**
+     * 瀛楀吀鍚嶇О
+     */
+    private String dictName;
+
+    /**
+     * 瀛楀吀绫诲瀷
+     */
+    private String dictType;
+
+    /**
+     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    private String status;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysLogininfor.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysLogininfor.java
new file mode 100644
index 0000000..f08dd61
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysLogininfor.java
@@ -0,0 +1,75 @@
+package org.dromara.system.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 绯荤粺璁块棶璁板綍琛� sys_logininfor
+ *
+ * @author Lion Li
+ */
+
+@Data
+@TableName("sys_logininfor")
+public class SysLogininfor implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * ID
+     */
+    @TableId(value = "info_id")
+    private Long infoId;
+
+    /**
+     * 绉熸埛缂栧彿
+     */
+    private String tenantId;
+
+    /**
+     * 鐢ㄦ埛璐﹀彿
+     */
+    private String userName;
+
+    /**
+     * 鐧诲綍鐘舵�� 0鎴愬姛 1澶辫触
+     */
+    private String status;
+
+    /**
+     * 鐧诲綍IP鍦板潃
+     */
+    private String ipaddr;
+
+    /**
+     * 鐧诲綍鍦扮偣
+     */
+    private String loginLocation;
+
+    /**
+     * 娴忚鍣ㄧ被鍨�
+     */
+    private String browser;
+
+    /**
+     * 鎿嶄綔绯荤粺
+     */
+    private String os;
+
+    /**
+     * 鎻愮ず娑堟伅
+     */
+    private String msg;
+
+    /**
+     * 璁块棶鏃堕棿
+     */
+    private Date loginTime;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMenu.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMenu.java
new file mode 100644
index 0000000..b8550bb
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMenu.java
@@ -0,0 +1,191 @@
+package org.dromara.system.domain;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import org.dromara.common.core.constant.Constants;
+import org.dromara.common.core.constant.UserConstants;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 鑿滃崟鏉冮檺琛� sys_menu
+ *
+ * @author Lion Li
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("sys_menu")
+public class SysMenu extends BaseEntity {
+
+    /**
+     * 鑿滃崟ID
+     */
+    @TableId(value = "menu_id")
+    private Long menuId;
+
+    /**
+     * 鐖惰彍鍗旾D
+     */
+    private Long parentId;
+
+    /**
+     * 鑿滃崟鍚嶇О
+     */
+    private String menuName;
+
+    /**
+     * 鏄剧ず椤哄簭
+     */
+    private Integer orderNum;
+
+    /**
+     * 璺敱鍦板潃
+     */
+    private String path;
+
+    /**
+     * 缁勪欢璺緞
+     */
+    private String component;
+
+    /**
+     * 璺敱鍙傛暟
+     */
+    private String queryParam;
+
+    /**
+     * 鏄惁涓哄閾撅紙0鏄� 1鍚︼級
+     */
+    private String isFrame;
+
+    /**
+     * 鏄惁缂撳瓨锛�0缂撳瓨 1涓嶇紦瀛橈級
+     */
+    private String isCache;
+
+    /**
+     * 绫诲瀷锛圡鐩綍 C鑿滃崟 F鎸夐挳锛�
+     */
+    private String menuType;
+
+    /**
+     * 鏄剧ず鐘舵�侊紙0鏄剧ず 1闅愯棌锛�
+     */
+    private String visible;
+
+    /**
+     * 鑿滃崟鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    private String status;
+
+    /**
+     * 鏉冮檺瀛楃涓�
+     */
+    private String perms;
+
+    /**
+     * 鑿滃崟鍥炬爣
+     */
+    private String icon;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+    /**
+     * 鐖惰彍鍗曞悕绉�
+     */
+    @TableField(exist = false)
+    private String parentName;
+
+    /**
+     * 瀛愯彍鍗�
+     */
+    @TableField(exist = false)
+    private List<SysMenu> children = new ArrayList<>();
+
+    /**
+     * 鑾峰彇璺敱鍚嶇О
+     */
+    public String getRouteName() {
+        String routerName = StringUtils.capitalize(path);
+        // 闈炲閾惧苟涓旀槸涓�绾х洰褰曪紙绫诲瀷涓虹洰褰曪級
+        if (isMenuFrame()) {
+            routerName = StringUtils.EMPTY;
+        }
+        return routerName;
+    }
+
+    /**
+     * 鑾峰彇璺敱鍦板潃
+     */
+    public String getRouterPath() {
+        String routerPath = this.path;
+        // 鍐呴摼鎵撳紑澶栫綉鏂瑰紡
+        if (getParentId() != 0L && isInnerLink()) {
+            routerPath = innerLinkReplaceEach(routerPath);
+        }
+        // 闈炲閾惧苟涓旀槸涓�绾х洰褰曪紙绫诲瀷涓虹洰褰曪級
+        if (0L == getParentId() && UserConstants.TYPE_DIR.equals(getMenuType())
+            && UserConstants.NO_FRAME.equals(getIsFrame())) {
+            routerPath = "/" + this.path;
+        }
+        // 闈炲閾惧苟涓旀槸涓�绾х洰褰曪紙绫诲瀷涓鸿彍鍗曪級
+        else if (isMenuFrame()) {
+            routerPath = "/";
+        }
+        return routerPath;
+    }
+
+    /**
+     * 鑾峰彇缁勪欢淇℃伅
+     */
+    public String getComponentInfo() {
+        String component = UserConstants.LAYOUT;
+        if (StringUtils.isNotEmpty(this.component) && !isMenuFrame()) {
+            component = this.component;
+        } else if (StringUtils.isEmpty(this.component) && getParentId() != 0L && isInnerLink()) {
+            component = UserConstants.INNER_LINK;
+        } else if (StringUtils.isEmpty(this.component) && isParentView()) {
+            component = UserConstants.PARENT_VIEW;
+        }
+        return component;
+    }
+
+    /**
+     * 鏄惁涓鸿彍鍗曞唴閮ㄨ烦杞�
+     */
+    public boolean isMenuFrame() {
+        return getParentId() == 0L && UserConstants.TYPE_MENU.equals(menuType) && isFrame.equals(UserConstants.NO_FRAME);
+    }
+
+    /**
+     * 鏄惁涓哄唴閾剧粍浠�
+     */
+    public boolean isInnerLink() {
+        return isFrame.equals(UserConstants.NO_FRAME) && StringUtils.ishttp(path);
+    }
+
+    /**
+     * 鏄惁涓簆arent_view缁勪欢
+     */
+    public boolean isParentView() {
+        return getParentId() != 0L && UserConstants.TYPE_DIR.equals(menuType);
+    }
+
+    /**
+     * 鍐呴摼鍩熷悕鐗规畩瀛楃鏇挎崲
+     */
+    public static String innerLinkReplaceEach(String path) {
+        return StringUtils.replaceEach(path, new String[]{Constants.HTTP, Constants.HTTPS, Constants.WWW, "."},
+            new String[]{"", "", "", "/"});
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysNotice.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysNotice.java
new file mode 100644
index 0000000..bfcc2bc
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysNotice.java
@@ -0,0 +1,51 @@
+package org.dromara.system.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import org.dromara.common.tenant.core.TenantEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+
+/**
+ * 閫氱煡鍏憡琛� sys_notice
+ *
+ * @author Lion Li
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("sys_notice")
+public class SysNotice extends TenantEntity {
+
+    /**
+     * 鍏憡ID
+     */
+    @TableId(value = "notice_id")
+    private Long noticeId;
+
+    /**
+     * 鍏憡鏍囬
+     */
+    private String noticeTitle;
+
+    /**
+     * 鍏憡绫诲瀷锛�1閫氱煡 2鍏憡锛�
+     */
+    private String noticeType;
+
+    /**
+     * 鍏憡鍐呭
+     */
+    private String noticeContent;
+
+    /**
+     * 鍏憡鐘舵�侊紙0姝e父 1鍏抽棴锛�
+     */
+    private String status;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysOperLog.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysOperLog.java
new file mode 100644
index 0000000..41a8c59
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysOperLog.java
@@ -0,0 +1,115 @@
+package org.dromara.system.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 鎿嶄綔鏃ュ織璁板綍琛� oper_log
+ *
+ * @author Lion Li
+ */
+
+@Data
+@TableName("sys_oper_log")
+public class SysOperLog implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鏃ュ織涓婚敭
+     */
+    @TableId(value = "oper_id")
+    private Long operId;
+
+    /**
+     * 绉熸埛缂栧彿
+     */
+    private String tenantId;
+
+    /**
+     * 鎿嶄綔妯″潡
+     */
+    private String title;
+
+    /**
+     * 涓氬姟绫诲瀷锛�0鍏跺畠 1鏂板 2淇敼 3鍒犻櫎锛�
+     */
+    private Integer businessType;
+
+    /**
+     * 璇锋眰鏂规硶
+     */
+    private String method;
+
+    /**
+     * 璇锋眰鏂瑰紡
+     */
+    private String requestMethod;
+
+    /**
+     * 鎿嶄綔绫诲埆锛�0鍏跺畠 1鍚庡彴鐢ㄦ埛 2鎵嬫満绔敤鎴凤級
+     */
+    private Integer operatorType;
+
+    /**
+     * 鎿嶄綔浜哄憳
+     */
+    private String operName;
+
+    /**
+     * 閮ㄩ棬鍚嶇О
+     */
+    private String deptName;
+
+    /**
+     * 璇锋眰url
+     */
+    private String operUrl;
+
+    /**
+     * 鎿嶄綔鍦板潃
+     */
+    private String operIp;
+
+    /**
+     * 鎿嶄綔鍦扮偣
+     */
+    private String operLocation;
+
+    /**
+     * 璇锋眰鍙傛暟
+     */
+    private String operParam;
+
+    /**
+     * 杩斿洖鍙傛暟
+     */
+    private String jsonResult;
+
+    /**
+     * 鎿嶄綔鐘舵�侊紙0姝e父 1寮傚父锛�
+     */
+    private Integer status;
+
+    /**
+     * 閿欒娑堟伅
+     */
+    private String errorMsg;
+
+    /**
+     * 鎿嶄綔鏃堕棿
+     */
+    private Date operTime;
+
+    /**
+     * 娑堣�楁椂闂�
+     */
+    private Long costTime;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysOss.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysOss.java
new file mode 100644
index 0000000..af88898
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysOss.java
@@ -0,0 +1,50 @@
+package org.dromara.system.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import org.dromara.common.tenant.core.TenantEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * OSS瀵硅薄瀛樺偍瀵硅薄
+ *
+ * @author Lion Li
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("sys_oss")
+public class SysOss extends TenantEntity {
+
+    /**
+     * 瀵硅薄瀛樺偍涓婚敭
+     */
+    @TableId(value = "oss_id")
+    private Long ossId;
+
+    /**
+     * 鏂囦欢鍚�
+     */
+    private String fileName;
+
+    /**
+     * 鍘熷悕
+     */
+    private String originalName;
+
+    /**
+     * 鏂囦欢鍚庣紑鍚�
+     */
+    private String fileSuffix;
+
+    /**
+     * URL鍦板潃
+     */
+    private String url;
+
+    /**
+     * 鏈嶅姟鍟�
+     */
+    private String service;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysOssConfig.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysOssConfig.java
new file mode 100644
index 0000000..de99496
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysOssConfig.java
@@ -0,0 +1,89 @@
+package org.dromara.system.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import org.dromara.common.tenant.core.TenantEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 瀵硅薄瀛樺偍閰嶇疆瀵硅薄 sys_oss_config
+ *
+ * @author Lion Li
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("sys_oss_config")
+public class SysOssConfig extends TenantEntity {
+
+    /**
+     * 涓诲缓
+     */
+    @TableId(value = "oss_config_id")
+    private Long ossConfigId;
+
+    /**
+     * 閰嶇疆key
+     */
+    private String configKey;
+
+    /**
+     * accessKey
+     */
+    private String accessKey;
+
+    /**
+     * 绉橀挜
+     */
+    private String secretKey;
+
+    /**
+     * 妗跺悕绉�
+     */
+    private String bucketName;
+
+    /**
+     * 鍓嶇紑
+     */
+    private String prefix;
+
+    /**
+     * 璁块棶绔欑偣
+     */
+    private String endpoint;
+
+    /**
+     * 鑷畾涔夊煙鍚�
+     */
+    private String domain;
+
+    /**
+     * 鏄惁https锛�0鍚� 1鏄級
+     */
+    private String isHttps;
+
+    /**
+     * 鍩�
+     */
+    private String region;
+
+    /**
+     * 鏄惁榛樿锛�0=鏄�,1=鍚︼級
+     */
+    private String status;
+
+    /**
+     * 鎵╁睍瀛楁
+     */
+    private String ext1;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+    /**
+     * 妗舵潈闄愮被鍨�(0private 1public 2custom)
+     */
+    private String accessPolicy;
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysPost.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysPost.java
new file mode 100644
index 0000000..7fe7039
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysPost.java
@@ -0,0 +1,51 @@
+package org.dromara.system.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import org.dromara.common.tenant.core.TenantEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 宀椾綅琛� sys_post
+ *
+ * @author Lion Li
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("sys_post")
+public class SysPost extends TenantEntity {
+
+    /**
+     * 宀椾綅搴忓彿
+     */
+    @TableId(value = "post_id")
+    private Long postId;
+
+    /**
+     * 宀椾綅缂栫爜
+     */
+    private String postCode;
+
+    /**
+     * 宀椾綅鍚嶇О
+     */
+    private String postName;
+
+    /**
+     * 宀椾綅鎺掑簭
+     */
+    private Integer postSort;
+
+    /**
+     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    private String status;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysRole.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysRole.java
new file mode 100644
index 0000000..2b42464
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysRole.java
@@ -0,0 +1,79 @@
+package org.dromara.system.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import org.dromara.common.tenant.core.TenantEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 瑙掕壊琛� sys_role
+ *
+ * @author Lion Li
+ */
+
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@TableName("sys_role")
+public class SysRole extends TenantEntity {
+
+    /**
+     * 瑙掕壊ID
+     */
+    @TableId(value = "role_id")
+    private Long roleId;
+
+    /**
+     * 瑙掕壊鍚嶇О
+     */
+    private String roleName;
+
+    /**
+     * 瑙掕壊鏉冮檺
+     */
+    private String roleKey;
+
+    /**
+     * 瑙掕壊鎺掑簭
+     */
+    private Integer roleSort;
+
+    /**
+     * 鏁版嵁鑼冨洿锛�1锛氭墍鏈夋暟鎹潈闄愶紱2锛氳嚜瀹氫箟鏁版嵁鏉冮檺锛�3锛氭湰閮ㄩ棬鏁版嵁鏉冮檺锛�4锛氭湰閮ㄩ棬鍙婁互涓嬫暟鎹潈闄愶紱5锛氫粎鏈汉鏁版嵁鏉冮檺锛�
+     */
+    private String dataScope;
+
+    /**
+     * 鑿滃崟鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀猴紙 0锛氱埗瀛愪笉浜掔浉鍏宠仈鏄剧ず 1锛氱埗瀛愪簰鐩稿叧鑱旀樉绀猴級
+     */
+    private Boolean menuCheckStrictly;
+
+    /**
+     * 閮ㄩ棬鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀猴紙0锛氱埗瀛愪笉浜掔浉鍏宠仈鏄剧ず 1锛氱埗瀛愪簰鐩稿叧鑱旀樉绀� 锛�
+     */
+    private Boolean deptCheckStrictly;
+
+    /**
+     * 瑙掕壊鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    private String status;
+
+    /**
+     * 鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛�
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+    public SysRole(Long roleId) {
+        this.roleId = roleId;
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysRoleDept.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysRoleDept.java
new file mode 100644
index 0000000..ba77694
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysRoleDept.java
@@ -0,0 +1,29 @@
+package org.dromara.system.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * 瑙掕壊鍜岄儴闂ㄥ叧鑱� sys_role_dept
+ *
+ * @author Lion Li
+ */
+
+@Data
+@TableName("sys_role_dept")
+public class SysRoleDept {
+
+    /**
+     * 瑙掕壊ID
+     */
+    @TableId(type = IdType.INPUT)
+    private Long roleId;
+
+    /**
+     * 閮ㄩ棬ID
+     */
+    private Long deptId;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysRoleMenu.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysRoleMenu.java
new file mode 100644
index 0000000..ba28f17
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysRoleMenu.java
@@ -0,0 +1,29 @@
+package org.dromara.system.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * 瑙掕壊鍜岃彍鍗曞叧鑱� sys_role_menu
+ *
+ * @author Lion Li
+ */
+
+@Data
+@TableName("sys_role_menu")
+public class SysRoleMenu {
+
+    /**
+     * 瑙掕壊ID
+     */
+    @TableId(type = IdType.INPUT)
+    private Long roleId;
+
+    /**
+     * 鑿滃崟ID
+     */
+    private Long menuId;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysTenant.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysTenant.java
new file mode 100644
index 0000000..a564a40
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysTenant.java
@@ -0,0 +1,103 @@
+package org.dromara.system.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+import java.util.Date;
+
+/**
+ * 绉熸埛瀵硅薄 sys_tenant
+ *
+ * @author Michelle.Chung
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("sys_tenant")
+public class SysTenant extends BaseEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * id
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 绉熸埛缂栧彿
+     */
+    private String tenantId;
+
+    /**
+     * 鑱旂郴浜�
+     */
+    private String contactUserName;
+
+    /**
+     * 鑱旂郴鐢佃瘽
+     */
+    private String contactPhone;
+
+    /**
+     * 浼佷笟鍚嶇О
+     */
+    private String companyName;
+
+    /**
+     * 缁熶竴绀句細淇$敤浠g爜
+     */
+    private String licenseNumber;
+
+    /**
+     * 鍦板潃
+     */
+    private String address;
+
+    /**
+     * 鍩熷悕
+     */
+    private String domain;
+
+    /**
+     * 浼佷笟绠�浠�
+     */
+    private String intro;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+    /**
+     * 绉熸埛濂楅缂栧彿
+     */
+    private Long packageId;
+
+    /**
+     * 杩囨湡鏃堕棿
+     */
+    private Date expireTime;
+
+    /**
+     * 鐢ㄦ埛鏁伴噺锛�-1涓嶉檺鍒讹級
+     */
+    private Long accountCount;
+
+    /**
+     * 绉熸埛鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    private String status;
+
+    /**
+     * 鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛�
+     */
+    @TableLogic
+    private String delFlag;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysTenantPackage.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysTenantPackage.java
new file mode 100644
index 0000000..f7e423f
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysTenantPackage.java
@@ -0,0 +1,54 @@
+package org.dromara.system.domain;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import java.io.Serial;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+
+/**
+ * 绉熸埛濂楅瀵硅薄 sys_tenant_package
+ *
+ * @author Michelle.Chung
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("sys_tenant_package")
+public class SysTenantPackage extends BaseEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 绉熸埛濂楅id
+     */
+    @TableId(value = "package_id")
+    private Long packageId;
+    /**
+     * 濂楅鍚嶇О
+     */
+    private String packageName;
+    /**
+     * 鍏宠仈鑿滃崟id
+     */
+    private String menuIds;
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+    /**
+     * 鑿滃崟鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀猴紙 0锛氱埗瀛愪笉浜掔浉鍏宠仈鏄剧ず 1锛氱埗瀛愪簰鐩稿叧鑱旀樉绀猴級
+     */
+    private Boolean menuCheckStrictly;
+    /**
+     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    private String status;
+    /**
+     * 鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛�
+     */
+    @TableLogic
+    private String delFlag;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUser.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUser.java
new file mode 100644
index 0000000..8dde40b
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUser.java
@@ -0,0 +1,115 @@
+package org.dromara.system.domain;
+
+import com.baomidou.mybatisplus.annotation.*;
+import org.dromara.common.core.constant.UserConstants;
+import org.dromara.common.tenant.core.TenantEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * 鐢ㄦ埛瀵硅薄 sys_user
+ *
+ * @author Lion Li
+ */
+
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@TableName("sys_user")
+public class SysUser extends TenantEntity {
+
+    /**
+     * 鐢ㄦ埛ID
+     */
+    @TableId(value = "user_id")
+    private Long userId;
+
+    /**
+     * 閮ㄩ棬ID
+     */
+    private Long deptId;
+
+    /**
+     * 鐢ㄦ埛璐﹀彿
+     */
+    private String userName;
+
+    /**
+     * 鐢ㄦ埛鏄电О
+     */
+    private String nickName;
+
+    /**
+     * 鐢ㄦ埛绫诲瀷锛坰ys_user绯荤粺鐢ㄦ埛锛�
+     */
+    private String userType;
+
+    /**
+     * 鐢ㄦ埛閭
+     */
+    private String email;
+
+    /**
+     * 鎵嬫満鍙风爜
+     */
+    private String phonenumber;
+
+    /**
+     * 鐢ㄦ埛鎬у埆
+     */
+    private String sex;
+
+    /**
+     * 鐢ㄦ埛澶村儚
+     */
+    private Long avatar;
+
+    /**
+     * 瀵嗙爜
+     */
+    @TableField(
+        insertStrategy = FieldStrategy.NOT_EMPTY,
+        updateStrategy = FieldStrategy.NOT_EMPTY,
+        whereStrategy = FieldStrategy.NOT_EMPTY
+    )
+    private String password;
+
+    /**
+     * 甯愬彿鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    private String status;
+
+    /**
+     * 鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛�
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 鏈�鍚庣櫥褰旾P
+     */
+    private String loginIp;
+
+    /**
+     * 鏈�鍚庣櫥褰曟椂闂�
+     */
+    private Date loginDate;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+
+    public SysUser(Long userId) {
+        this.userId = userId;
+    }
+
+    public boolean isSuperAdmin() {
+        return UserConstants.SUPER_ADMIN_ID.equals(this.userId);
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUserOnline.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUserOnline.java
new file mode 100644
index 0000000..fca680a
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUserOnline.java
@@ -0,0 +1,54 @@
+package org.dromara.system.domain;
+
+import lombok.Data;
+
+/**
+ * 褰撳墠鍦ㄧ嚎浼氳瘽
+ *
+ * @author Lion Li
+ */
+
+@Data
+public class SysUserOnline {
+
+    /**
+     * 浼氳瘽缂栧彿
+     */
+    private String tokenId;
+
+    /**
+     * 閮ㄩ棬鍚嶇О
+     */
+    private String deptName;
+
+    /**
+     * 鐢ㄦ埛鍚嶇О
+     */
+    private String userName;
+
+    /**
+     * 鐧诲綍IP鍦板潃
+     */
+    private String ipaddr;
+
+    /**
+     * 鐧诲綍鍦板潃
+     */
+    private String loginLocation;
+
+    /**
+     * 娴忚鍣ㄧ被鍨�
+     */
+    private String browser;
+
+    /**
+     * 鎿嶄綔绯荤粺
+     */
+    private String os;
+
+    /**
+     * 鐧诲綍鏃堕棿
+     */
+    private Long loginTime;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUserPost.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUserPost.java
new file mode 100644
index 0000000..119c117
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUserPost.java
@@ -0,0 +1,29 @@
+package org.dromara.system.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * 鐢ㄦ埛鍜屽矖浣嶅叧鑱� sys_user_post
+ *
+ * @author Lion Li
+ */
+
+@Data
+@TableName("sys_user_post")
+public class SysUserPost {
+
+    /**
+     * 鐢ㄦ埛ID
+     */
+    @TableId(type = IdType.INPUT)
+    private Long userId;
+
+    /**
+     * 宀椾綅ID
+     */
+    private Long postId;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUserRole.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUserRole.java
new file mode 100644
index 0000000..0a50e80
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUserRole.java
@@ -0,0 +1,29 @@
+package org.dromara.system.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * 鐢ㄦ埛鍜岃鑹插叧鑱� sys_user_role
+ *
+ * @author Lion Li
+ */
+
+@Data
+@TableName("sys_user_role")
+public class SysUserRole {
+
+    /**
+     * 鐢ㄦ埛ID
+     */
+    @TableId(type = IdType.INPUT)
+    private Long userId;
+
+    /**
+     * 瑙掕壊ID
+     */
+    private Long roleId;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysConfigBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysConfigBo.java
new file mode 100644
index 0000000..757af85
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysConfigBo.java
@@ -0,0 +1,62 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.system.domain.SysConfig;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+
+/**
+ * 鍙傛暟閰嶇疆涓氬姟瀵硅薄 sys_config
+ *
+ * @author Michelle.Chung
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = SysConfig.class, reverseConvertGenerate = false)
+public class SysConfigBo extends BaseEntity {
+
+    /**
+     * 鍙傛暟涓婚敭
+     */
+    @NotNull(message = "鍙傛暟涓婚敭涓嶈兘涓虹┖", groups = { EditGroup.class })
+    private Long configId;
+
+    /**
+     * 鍙傛暟鍚嶇О
+     */
+    @NotBlank(message = "鍙傛暟鍚嶇О涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
+    @Size(min = 0, max = 100, message = "鍙傛暟鍚嶇О涓嶈兘瓒呰繃{max}涓瓧绗�")
+    private String configName;
+
+    /**
+     * 鍙傛暟閿悕
+     */
+    @NotBlank(message = "鍙傛暟閿悕涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
+    @Size(min = 0, max = 100, message = "鍙傛暟閿悕闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
+    private String configKey;
+
+    /**
+     * 鍙傛暟閿��
+     */
+    @NotBlank(message = "鍙傛暟閿�间笉鑳戒负绌�", groups = { AddGroup.class, EditGroup.class })
+    @Size(min = 0, max = 500, message = "鍙傛暟閿�奸暱搴︿笉鑳借秴杩噞max}涓瓧绗�")
+    private String configValue;
+
+    /**
+     * 绯荤粺鍐呯疆锛圷鏄� N鍚︼級
+     */
+    private String configType;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDeptBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDeptBo.java
new file mode 100644
index 0000000..44f4052
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDeptBo.java
@@ -0,0 +1,73 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.system.domain.SysDept;
+import io.github.linpeilie.annotations.AutoMapper;
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 閮ㄩ棬涓氬姟瀵硅薄 sys_dept
+ *
+ * @author Michelle.Chung
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = SysDept.class, reverseConvertGenerate = false)
+public class SysDeptBo extends BaseEntity {
+
+    /**
+     * 閮ㄩ棬id
+     */
+    @NotNull(message = "閮ㄩ棬id涓嶈兘涓虹┖", groups = { EditGroup.class })
+    private Long deptId;
+
+    /**
+     * 鐖堕儴闂↖D
+     */
+    private Long parentId;
+
+    /**
+     * 閮ㄩ棬鍚嶇О
+     */
+    @NotBlank(message = "閮ㄩ棬鍚嶇О涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
+    @Size(min = 0, max = 30, message = "閮ㄩ棬鍚嶇О闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
+    private String deptName;
+
+    /**
+     * 鏄剧ず椤哄簭
+     */
+    @NotNull(message = "鏄剧ず椤哄簭涓嶈兘涓虹┖")
+    private Integer orderNum;
+
+    /**
+     * 璐熻矗浜�
+     */
+    private String leader;
+
+    /**
+     * 鑱旂郴鐢佃瘽
+     */
+    @Size(min = 0, max = 11, message = "鑱旂郴鐢佃瘽闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
+    private String phone;
+
+    /**
+     * 閭
+     */
+    @Email(message = "閭鏍煎紡涓嶆纭�")
+    @Size(min = 0, max = 50, message = "閭闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
+    private String email;
+
+    /**
+     * 閮ㄩ棬鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    private String status;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDictDataBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDictDataBo.java
new file mode 100644
index 0000000..3990de3
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDictDataBo.java
@@ -0,0 +1,88 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.system.domain.SysDictData;
+import io.github.linpeilie.annotations.AutoMapper;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 瀛楀吀鏁版嵁涓氬姟瀵硅薄 sys_dict_data
+ *
+ * @author Michelle.Chung
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = SysDictData.class, reverseConvertGenerate = false)
+public class SysDictDataBo extends BaseEntity {
+
+    /**
+     * 瀛楀吀缂栫爜
+     */
+    @NotNull(message = "瀛楀吀缂栫爜涓嶈兘涓虹┖", groups = { EditGroup.class })
+    private Long dictCode;
+
+    /**
+     * 瀛楀吀鎺掑簭
+     */
+    private Integer dictSort;
+
+    /**
+     * 瀛楀吀鏍囩
+     */
+    @NotBlank(message = "瀛楀吀鏍囩涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
+    @Size(min = 0, max = 100, message = "瀛楀吀鏍囩闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
+    private String dictLabel;
+
+    /**
+     * 瀛楀吀閿��
+     */
+    @NotBlank(message = "瀛楀吀閿�间笉鑳戒负绌�", groups = { AddGroup.class, EditGroup.class })
+    @Size(min = 0, max = 100, message = "瀛楀吀閿�奸暱搴︿笉鑳借秴杩噞max}涓瓧绗�")
+    private String dictValue;
+
+    /**
+     * 瀛楀吀绫诲瀷
+     */
+    @NotBlank(message = "瀛楀吀绫诲瀷涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
+    @Size(min = 0, max = 100, message = "瀛楀吀绫诲瀷闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
+    private String dictType;
+
+    /**
+     * 鏍峰紡灞炴�э紙鍏朵粬鏍峰紡鎵╁睍锛�
+     */
+    @Size(min = 0, max = 100, message = "鏍峰紡灞炴�ч暱搴︿笉鑳借秴杩噞max}涓瓧绗�")
+    private String cssClass;
+
+    /**
+     * 琛ㄦ牸鍥炴樉鏍峰紡
+     */
+    private String listClass;
+
+    /**
+     * 鏄惁榛樿锛圷鏄� N鍚︼級
+     */
+    private String isDefault;
+
+    /**
+     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    private String status;
+
+    /**
+     * 鍒涘缓閮ㄩ棬
+     */
+    private Long createDept;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDictTypeBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDictTypeBo.java
new file mode 100644
index 0000000..2fac7ea
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDictTypeBo.java
@@ -0,0 +1,58 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.system.domain.SysDictType;
+import io.github.linpeilie.annotations.AutoMapper;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Pattern;
+import jakarta.validation.constraints.Size;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 瀛楀吀绫诲瀷涓氬姟瀵硅薄 sys_dict_type
+ *
+ * @author Michelle.Chung
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = SysDictType.class, reverseConvertGenerate = false)
+public class SysDictTypeBo extends BaseEntity {
+
+    /**
+     * 瀛楀吀涓婚敭
+     */
+    @NotNull(message = "瀛楀吀涓婚敭涓嶈兘涓虹┖", groups = { EditGroup.class })
+    private Long dictId;
+
+    /**
+     * 瀛楀吀鍚嶇О
+     */
+    @NotBlank(message = "瀛楀吀鍚嶇О涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
+    @Size(min = 0, max = 100, message = "瀛楀吀绫诲瀷鍚嶇О闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
+    private String dictName;
+
+    /**
+     * 瀛楀吀绫诲瀷
+     */
+    @NotBlank(message = "瀛楀吀绫诲瀷涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
+    @Size(min = 0, max = 100, message = "瀛楀吀绫诲瀷绫诲瀷闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
+    @Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "瀛楀吀绫诲瀷蹇呴』浠ュ瓧姣嶅紑澶达紝涓斿彧鑳戒负锛堝皬鍐欏瓧姣嶏紝鏁板瓧锛屼笅婊戠嚎锛�")
+    private String dictType;
+
+    /**
+     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    private String status;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysLogininforBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysLogininforBo.java
new file mode 100644
index 0000000..564f86b
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysLogininforBo.java
@@ -0,0 +1,77 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.system.domain.SysLogininfor;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 绯荤粺璁块棶璁板綍涓氬姟瀵硅薄 sys_logininfor
+ *
+ * @author Michelle.Chung
+ */
+
+@Data
+@AutoMapper(target = SysLogininfor.class, reverseConvertGenerate = false)
+public class SysLogininforBo {
+
+    /**
+     * 璁块棶ID
+     */
+    private Long infoId;
+
+    /**
+     * 绉熸埛缂栧彿
+     */
+    private String tenantId;
+
+    /**
+     * 鐢ㄦ埛璐﹀彿
+     */
+    private String userName;
+
+    /**
+     * 鐧诲綍IP鍦板潃
+     */
+    private String ipaddr;
+
+    /**
+     * 鐧诲綍鍦扮偣
+     */
+    private String loginLocation;
+
+    /**
+     * 娴忚鍣ㄧ被鍨�
+     */
+    private String browser;
+
+    /**
+     * 鎿嶄綔绯荤粺
+     */
+    private String os;
+
+    /**
+     * 鐧诲綍鐘舵�侊紙0鎴愬姛 1澶辫触锛�
+     */
+    private String status;
+
+    /**
+     * 鎻愮ず娑堟伅
+     */
+    private String msg;
+
+    /**
+     * 璁块棶鏃堕棿
+     */
+    private Date loginTime;
+
+    /**
+     * 璇锋眰鍙傛暟
+     */
+    private Map<String, Object> params = new HashMap<>();
+
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysMenuBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysMenuBo.java
new file mode 100644
index 0000000..203b823
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysMenuBo.java
@@ -0,0 +1,111 @@
+package org.dromara.system.domain.bo;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.system.domain.SysMenu;
+import io.github.linpeilie.annotations.AutoMapper;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 鑿滃崟鏉冮檺涓氬姟瀵硅薄 sys_menu
+ *
+ * @author Michelle.Chung
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = SysMenu.class, reverseConvertGenerate = false)
+public class SysMenuBo extends BaseEntity {
+
+    /**
+     * 鑿滃崟ID
+     */
+    @NotNull(message = "鑿滃崟ID涓嶈兘涓虹┖", groups = { EditGroup.class })
+    private Long menuId;
+
+    /**
+     * 鐖惰彍鍗旾D
+     */
+    private Long parentId;
+
+    /**
+     * 鑿滃崟鍚嶇О
+     */
+    @NotBlank(message = "鑿滃崟鍚嶇О涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
+    @Size(min = 0, max = 50, message = "鑿滃崟鍚嶇О闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
+    private String menuName;
+
+    /**
+     * 鏄剧ず椤哄簭
+     */
+    @NotNull(message = "鏄剧ず椤哄簭涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
+    private Integer orderNum;
+
+    /**
+     * 璺敱鍦板潃
+     */
+    @Size(min = 0, max = 200, message = "璺敱鍦板潃涓嶈兘瓒呰繃{max}涓瓧绗�")
+    private String path;
+
+    /**
+     * 缁勪欢璺緞
+     */
+    @Size(min = 0, max = 200, message = "缁勪欢璺緞涓嶈兘瓒呰繃{max}涓瓧绗�")
+    private String component;
+
+    /**
+     * 璺敱鍙傛暟
+     */
+    private String queryParam;
+
+    /**
+     * 鏄惁涓哄閾撅紙0鏄� 1鍚︼級
+     */
+    private String isFrame;
+
+    /**
+     * 鏄惁缂撳瓨锛�0缂撳瓨 1涓嶇紦瀛橈級
+     */
+    private String isCache;
+
+    /**
+     * 鑿滃崟绫诲瀷锛圡鐩綍 C鑿滃崟 F鎸夐挳锛�
+     */
+    @NotBlank(message = "鑿滃崟绫诲瀷涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
+    private String menuType;
+
+    /**
+     * 鏄剧ず鐘舵�侊紙0鏄剧ず 1闅愯棌锛�
+     */
+    private String visible;
+
+    /**
+     * 鑿滃崟鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    private String status;
+
+    /**
+     * 鏉冮檺鏍囪瘑
+     */
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    @Size(min = 0, max = 100, message = "鏉冮檺鏍囪瘑闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
+    private String perms;
+
+    /**
+     * 鑿滃崟鍥炬爣
+     */
+    private String icon;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysNoticeBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysNoticeBo.java
new file mode 100644
index 0000000..e94366b
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysNoticeBo.java
@@ -0,0 +1,65 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.core.xss.Xss;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.system.domain.SysNotice;
+import io.github.linpeilie.annotations.AutoMapper;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 閫氱煡鍏憡涓氬姟瀵硅薄 sys_notice
+ *
+ * @author Michelle.Chung
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = SysNotice.class, reverseConvertGenerate = false)
+public class SysNoticeBo extends BaseEntity {
+
+    /**
+     * 鍏憡ID
+     */
+    @NotNull(message = "鍏憡ID涓嶈兘涓虹┖", groups = { EditGroup.class })
+    private Long noticeId;
+
+    /**
+     * 鍏憡鏍囬
+     */
+    @Xss(message = "鍏憡鏍囬涓嶈兘鍖呭惈鑴氭湰瀛楃")
+    @NotBlank(message = "鍏憡鏍囬涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
+    @Size(min = 0, max = 50, message = "鍏憡鏍囬涓嶈兘瓒呰繃{max}涓瓧绗�")
+    private String noticeTitle;
+
+    /**
+     * 鍏憡绫诲瀷锛�1閫氱煡 2鍏憡锛�
+     */
+    private String noticeType;
+
+    /**
+     * 鍏憡鍐呭
+     */
+    private String noticeContent;
+
+    /**
+     * 鍏憡鐘舵�侊紙0姝e父 1鍏抽棴锛�
+     */
+    private String status;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+    /**
+     * 鍒涘缓浜哄悕绉�
+     */
+    private String createByName;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysOperLogBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysOperLogBo.java
new file mode 100644
index 0000000..f16400a
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysOperLogBo.java
@@ -0,0 +1,127 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.common.log.event.OperLogEvent;
+import org.dromara.system.domain.SysOperLog;
+import io.github.linpeilie.annotations.AutoMapper;
+import io.github.linpeilie.annotations.AutoMappers;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 鎿嶄綔鏃ュ織璁板綍涓氬姟瀵硅薄 sys_oper_log
+ *
+ * @author Michelle.Chung
+ * @date 2023-02-07
+ */
+
+@Data
+@AutoMappers({
+    @AutoMapper(target = SysOperLog.class, reverseConvertGenerate = false),
+    @AutoMapper(target = OperLogEvent.class)
+})
+public class SysOperLogBo {
+
+    /**
+     * 鏃ュ織涓婚敭
+     */
+    private Long operId;
+
+    /**
+     * 绉熸埛缂栧彿
+     */
+    private String tenantId;
+
+    /**
+     * 妯″潡鏍囬
+     */
+    private String title;
+
+    /**
+     * 涓氬姟绫诲瀷锛�0鍏跺畠 1鏂板 2淇敼 3鍒犻櫎锛�
+     */
+    private Integer businessType;
+
+    /**
+     * 涓氬姟绫诲瀷鏁扮粍
+     */
+    private Integer[] businessTypes;
+
+    /**
+     * 鏂规硶鍚嶇О
+     */
+    private String method;
+
+    /**
+     * 璇锋眰鏂瑰紡
+     */
+    private String requestMethod;
+
+    /**
+     * 鎿嶄綔绫诲埆锛�0鍏跺畠 1鍚庡彴鐢ㄦ埛 2鎵嬫満绔敤鎴凤級
+     */
+    private Integer operatorType;
+
+    /**
+     * 鎿嶄綔浜哄憳
+     */
+    private String operName;
+
+    /**
+     * 閮ㄩ棬鍚嶇О
+     */
+    private String deptName;
+
+    /**
+     * 璇锋眰URL
+     */
+    private String operUrl;
+
+    /**
+     * 涓绘満鍦板潃
+     */
+    private String operIp;
+
+    /**
+     * 鎿嶄綔鍦扮偣
+     */
+    private String operLocation;
+
+    /**
+     * 璇锋眰鍙傛暟
+     */
+    private String operParam;
+
+    /**
+     * 杩斿洖鍙傛暟
+     */
+    private String jsonResult;
+
+    /**
+     * 鎿嶄綔鐘舵�侊紙0姝e父 1寮傚父锛�
+     */
+    private Integer status;
+
+    /**
+     * 閿欒娑堟伅
+     */
+    private String errorMsg;
+
+    /**
+     * 鎿嶄綔鏃堕棿
+     */
+    private Date operTime;
+
+    /**
+     * 娑堣�楁椂闂�
+     */
+    private Long costTime;
+
+    /**
+     * 璇锋眰鍙傛暟
+     */
+    private Map<String, Object> params = new HashMap<>();
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysOssBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysOssBo.java
new file mode 100644
index 0000000..7cb3104
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysOssBo.java
@@ -0,0 +1,49 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.system.domain.SysOss;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * OSS瀵硅薄瀛樺偍鍒嗛〉鏌ヨ瀵硅薄 sys_oss
+ *
+ * @author Lion Li
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = SysOss.class, reverseConvertGenerate = false)
+public class SysOssBo extends BaseEntity {
+
+    /**
+     * ossId
+     */
+    private Long ossId;
+
+    /**
+     * 鏂囦欢鍚�
+     */
+    private String fileName;
+
+    /**
+     * 鍘熷悕
+     */
+    private String originalName;
+
+    /**
+     * 鏂囦欢鍚庣紑鍚�
+     */
+    private String fileSuffix;
+
+    /**
+     * URL鍦板潃
+     */
+    private String url;
+
+    /**
+     * 鏈嶅姟鍟�
+     */
+    private String service;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysOssConfigBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysOssConfigBo.java
new file mode 100644
index 0000000..5887ded
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysOssConfigBo.java
@@ -0,0 +1,109 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.system.domain.SysOssConfig;
+import io.github.linpeilie.annotations.AutoMapper;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 瀵硅薄瀛樺偍閰嶇疆涓氬姟瀵硅薄 sys_oss_config
+ *
+ * @author Lion Li
+ * @author 瀛よ垷鐑熼洦
+ * @date 2021-08-13
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = SysOssConfig.class, reverseConvertGenerate = false)
+public class SysOssConfigBo extends BaseEntity {
+
+    /**
+     * 涓诲缓
+     */
+    @NotNull(message = "涓诲缓涓嶈兘涓虹┖", groups = {EditGroup.class})
+    private Long ossConfigId;
+
+    /**
+     * 閰嶇疆key
+     */
+    @NotBlank(message = "閰嶇疆key涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
+    @Size(min = 2, max = 100, message = "configKey闀垮害蹇呴』浠嬩簬{min}鍜寋max} 涔嬮棿")
+    private String configKey;
+
+    /**
+     * accessKey
+     */
+    @NotBlank(message = "accessKey涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
+    @Size(min = 2, max = 100, message = "accessKey闀垮害蹇呴』浠嬩簬{min}鍜寋max} 涔嬮棿")
+    private String accessKey;
+
+    /**
+     * 绉橀挜
+     */
+    @NotBlank(message = "secretKey涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
+    @Size(min = 2, max = 100, message = "secretKey闀垮害蹇呴』浠嬩簬{min}鍜寋max} 涔嬮棿")
+    private String secretKey;
+
+    /**
+     * 妗跺悕绉�
+     */
+    @NotBlank(message = "妗跺悕绉颁笉鑳戒负绌�", groups = {AddGroup.class, EditGroup.class})
+    @Size(min = 2, max = 100, message = "bucketName闀垮害蹇呴』浠嬩簬{min}鍜寋max}涔嬮棿")
+    private String bucketName;
+
+    /**
+     * 鍓嶇紑
+     */
+    private String prefix;
+
+    /**
+     * 璁块棶绔欑偣
+     */
+    @NotBlank(message = "璁块棶绔欑偣涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
+    @Size(min = 2, max = 100, message = "endpoint闀垮害蹇呴』浠嬩簬{min}鍜寋max}涔嬮棿")
+    private String endpoint;
+
+    /**
+     * 鑷畾涔夊煙鍚�
+     */
+    private String domain;
+
+    /**
+     * 鏄惁https锛圷=鏄�,N=鍚︼級
+     */
+    private String isHttps;
+
+    /**
+     * 鏄惁榛樿锛�0=鏄�,1=鍚︼級
+     */
+    private String status;
+
+    /**
+     * 鍩�
+     */
+    private String region;
+
+    /**
+     * 鎵╁睍瀛楁
+     */
+    private String ext1;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+    /**
+     * 妗舵潈闄愮被鍨�(0private 1public 2custom)
+     */
+    @NotBlank(message = "妗舵潈闄愮被鍨嬩笉鑳戒负绌�", groups = {AddGroup.class, EditGroup.class})
+    private String accessPolicy;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysPostBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysPostBo.java
new file mode 100644
index 0000000..7bb176b
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysPostBo.java
@@ -0,0 +1,62 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.system.domain.SysPost;
+import io.github.linpeilie.annotations.AutoMapper;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 宀椾綅淇℃伅涓氬姟瀵硅薄 sys_post
+ *
+ * @author Michelle.Chung
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = SysPost.class, reverseConvertGenerate = false)
+public class SysPostBo extends BaseEntity {
+
+    /**
+     * 宀椾綅ID
+     */
+    @NotNull(message = "宀椾綅ID涓嶈兘涓虹┖", groups = { EditGroup.class })
+    private Long postId;
+
+    /**
+     * 宀椾綅缂栫爜
+     */
+    @NotBlank(message = "宀椾綅缂栫爜涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
+    @Size(min = 0, max = 64, message = "宀椾綅缂栫爜闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
+    private String postCode;
+
+    /**
+     * 宀椾綅鍚嶇О
+     */
+    @NotBlank(message = "宀椾綅鍚嶇О涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
+    @Size(min = 0, max = 50, message = "宀椾綅鍚嶇О闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
+    private String postName;
+
+    /**
+     * 鏄剧ず椤哄簭
+     */
+    @NotNull(message = "鏄剧ず椤哄簭涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
+    private Integer postSort;
+
+    /**
+     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    private String status;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysRoleBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysRoleBo.java
new file mode 100644
index 0000000..94fb31e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysRoleBo.java
@@ -0,0 +1,97 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.common.core.constant.UserConstants;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.system.domain.SysRole;
+import io.github.linpeilie.annotations.AutoMapper;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 瑙掕壊淇℃伅涓氬姟瀵硅薄 sys_role
+ *
+ * @author Michelle.Chung
+ */
+
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = SysRole.class, reverseConvertGenerate = false)
+public class SysRoleBo extends BaseEntity {
+
+    /**
+     * 瑙掕壊ID
+     */
+    @NotNull(message = "瑙掕壊ID涓嶈兘涓虹┖", groups = { EditGroup.class })
+    private Long roleId;
+
+    /**
+     * 瑙掕壊鍚嶇О
+     */
+    @NotBlank(message = "瑙掕壊鍚嶇О涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
+    @Size(min = 0, max = 30, message = "瑙掕壊鍚嶇О闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
+    private String roleName;
+
+    /**
+     * 瑙掕壊鏉冮檺瀛楃涓�
+     */
+    @NotBlank(message = "瑙掕壊鏉冮檺瀛楃涓蹭笉鑳戒负绌�", groups = { AddGroup.class, EditGroup.class })
+    @Size(min = 0, max = 100, message = "鏉冮檺瀛楃闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
+    private String roleKey;
+
+    /**
+     * 鏄剧ず椤哄簭
+     */
+    @NotNull(message = "鏄剧ず椤哄簭涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
+    private Integer roleSort;
+
+    /**
+     * 鏁版嵁鑼冨洿锛�1锛氬叏閮ㄦ暟鎹潈闄� 2锛氳嚜瀹氭暟鎹潈闄� 3锛氭湰閮ㄩ棬鏁版嵁鏉冮檺 4锛氭湰閮ㄩ棬鍙婁互涓嬫暟鎹潈闄愶級
+     */
+    private String dataScope;
+
+    /**
+     * 鑿滃崟鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�
+     */
+    private Boolean menuCheckStrictly;
+
+    /**
+     * 閮ㄩ棬鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�
+     */
+    private Boolean deptCheckStrictly;
+
+    /**
+     * 瑙掕壊鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    private String status;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+    /**
+     * 鑿滃崟缁�
+     */
+    private Long[] menuIds;
+
+    /**
+     * 閮ㄩ棬缁勶紙鏁版嵁鏉冮檺锛�
+     */
+    private Long[] deptIds;
+
+    public SysRoleBo(Long roleId) {
+        this.roleId = roleId;
+    }
+
+    public boolean isSuperAdmin() {
+        return UserConstants.SUPER_ADMIN_ID.equals(this.roleId);
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysTenantBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysTenantBo.java
new file mode 100644
index 0000000..e3ac642
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysTenantBo.java
@@ -0,0 +1,114 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.system.domain.SysTenant;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+import java.util.Date;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+
+/**
+ * 绉熸埛涓氬姟瀵硅薄 sys_tenant
+ *
+ * @author Michelle.Chung
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = SysTenant.class, reverseConvertGenerate = false)
+public class SysTenantBo extends BaseEntity {
+
+    /**
+     * id
+     */
+    @NotNull(message = "id涓嶈兘涓虹┖", groups = { EditGroup.class })
+    private Long id;
+
+    /**
+     * 绉熸埛缂栧彿
+     */
+    private String tenantId;
+
+    /**
+     * 鑱旂郴浜�
+     */
+    @NotBlank(message = "鑱旂郴浜轰笉鑳戒负绌�", groups = { AddGroup.class, EditGroup.class })
+    private String contactUserName;
+
+    /**
+     * 鑱旂郴鐢佃瘽
+     */
+    @NotBlank(message = "鑱旂郴鐢佃瘽涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
+    private String contactPhone;
+
+    /**
+     * 浼佷笟鍚嶇О
+     */
+    @NotBlank(message = "浼佷笟鍚嶇О涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
+    private String companyName;
+
+    /**
+     * 鐢ㄦ埛鍚嶏紙鍒涘缓绯荤粺鐢ㄦ埛锛�
+     */
+    @NotBlank(message = "鐢ㄦ埛鍚嶄笉鑳戒负绌�", groups = { AddGroup.class })
+    private String username;
+
+    /**
+     * 瀵嗙爜锛堝垱寤虹郴缁熺敤鎴凤級
+     */
+    @NotBlank(message = "瀵嗙爜涓嶈兘涓虹┖", groups = { AddGroup.class })
+    private String password;
+
+    /**
+     * 缁熶竴绀句細淇$敤浠g爜
+     */
+    private String licenseNumber;
+
+    /**
+     * 鍦板潃
+     */
+    private String address;
+
+    /**
+     * 鍩熷悕
+     */
+    private String domain;
+
+    /**
+     * 浼佷笟绠�浠�
+     */
+    private String intro;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+    /**
+     * 绉熸埛濂楅缂栧彿
+     */
+    @NotNull(message = "绉熸埛濂楅涓嶈兘涓虹┖", groups = { AddGroup.class })
+    private Long packageId;
+
+    /**
+     * 杩囨湡鏃堕棿
+     */
+    private Date expireTime;
+
+    /**
+     * 鐢ㄦ埛鏁伴噺锛�-1涓嶉檺鍒讹級
+     */
+    private Long accountCount;
+
+    /**
+     * 绉熸埛鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    private String status;
+
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysTenantPackageBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysTenantPackageBo.java
new file mode 100644
index 0000000..eecbc9f
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysTenantPackageBo.java
@@ -0,0 +1,59 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.system.domain.SysTenantPackage;
+import io.github.linpeilie.annotations.AutoMapper;
+import io.github.linpeilie.annotations.AutoMapping;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+
+/**
+ * 绉熸埛濂楅涓氬姟瀵硅薄 sys_tenant_package
+ *
+ * @author Michelle.Chung
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = SysTenantPackage.class, reverseConvertGenerate = false)
+public class SysTenantPackageBo extends BaseEntity {
+
+    /**
+     * 绉熸埛濂楅id
+     */
+    @NotNull(message = "绉熸埛濂楅id涓嶈兘涓虹┖", groups = { EditGroup.class })
+    private Long packageId;
+
+    /**
+     * 濂楅鍚嶇О
+     */
+    @NotBlank(message = "濂楅鍚嶇О涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
+    private String packageName;
+
+    /**
+     * 鍏宠仈鑿滃崟id
+     */
+    @AutoMapping(target = "menuIds", expression = "java(org.dromara.common.core.utils.StringUtils.join(source.getMenuIds(), \",\"))")
+    private Long[] menuIds;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+    /**
+     * 鑿滃崟鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�
+     */
+    private Boolean menuCheckStrictly;
+
+    /**
+     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    private String status;
+
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java
new file mode 100644
index 0000000..04d1ce0
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java
@@ -0,0 +1,134 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.common.core.constant.UserConstants;
+import org.dromara.common.core.xss.Xss;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.sensitive.annotation.Sensitive;
+import org.dromara.common.sensitive.core.SensitiveStrategy;
+import org.dromara.system.domain.SysUser;
+import io.github.linpeilie.annotations.AutoMapper;
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Size;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * 鐢ㄦ埛淇℃伅涓氬姟瀵硅薄 sys_user
+ *
+ * @author Michelle.Chung
+ */
+
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = SysUser.class, reverseConvertGenerate = false)
+public class SysUserBo extends BaseEntity {
+
+    /**
+     * 鐢ㄦ埛ID
+     */
+    private Long userId;
+
+    /**
+     * 閮ㄩ棬ID
+     */
+    private Long deptId;
+
+    /**
+     * 鐢ㄦ埛璐﹀彿
+     */
+    @Xss(message = "鐢ㄦ埛璐﹀彿涓嶈兘鍖呭惈鑴氭湰瀛楃")
+    @NotBlank(message = "鐢ㄦ埛璐﹀彿涓嶈兘涓虹┖")
+    @Size(min = 0, max = 30, message = "鐢ㄦ埛璐﹀彿闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
+    private String userName;
+
+    /**
+     * 鐢ㄦ埛鏄电О
+     */
+    @Xss(message = "鐢ㄦ埛鏄电О涓嶈兘鍖呭惈鑴氭湰瀛楃")
+    @Size(min = 0, max = 30, message = "鐢ㄦ埛鏄电О闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
+    private String nickName;
+
+    /**
+     * 鐢ㄦ埛绫诲瀷锛坰ys_user绯荤粺鐢ㄦ埛锛�
+     */
+    private String userType;
+
+    /**
+     * 鐢ㄦ埛閭
+     */
+    @Sensitive(strategy = SensitiveStrategy.EMAIL)
+    @Email(message = "閭鏍煎紡涓嶆纭�")
+    @Size(min = 0, max = 50, message = "閭闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
+    private String email;
+
+    /**
+     * 鎵嬫満鍙风爜
+     */
+    @Sensitive(strategy = SensitiveStrategy.PHONE)
+    private String phonenumber;
+
+    /**
+     * 鐢ㄦ埛鎬у埆锛�0鐢� 1濂� 2鏈煡锛�
+     */
+    private String sex;
+
+    /**
+     * 澶村儚鍦板潃
+     */
+    private Long avatar;
+
+    /**
+     * 瀵嗙爜
+     */
+    private String password;
+
+    /**
+     * 甯愬彿鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    private String status;
+
+    /**
+     * 鏈�鍚庣櫥褰旾P
+     */
+    private String loginIp;
+
+    /**
+     * 鏈�鍚庣櫥褰曟椂闂�
+     */
+    private Date loginDate;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+    /**
+     * 瑙掕壊缁�
+     */
+    @Size(min = 1, message = "鐢ㄦ埛瑙掕壊涓嶈兘涓虹┖")
+    private Long[] roleIds;
+
+    /**
+     * 宀椾綅缁�
+     */
+    private Long[] postIds;
+
+    /**
+     * 鏁版嵁鏉冮檺 褰撳墠瑙掕壊ID
+     */
+    private Long roleId;
+
+    public SysUserBo(Long userId) {
+        this.userId = userId;
+    }
+
+    public boolean isSuperAdmin() {
+        return UserConstants.SUPER_ADMIN_ID.equals(this.userId);
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserProfileBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserProfileBo.java
new file mode 100644
index 0000000..fb4c605
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserProfileBo.java
@@ -0,0 +1,55 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.common.core.xss.Xss;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.sensitive.annotation.Sensitive;
+import org.dromara.common.sensitive.core.SensitiveStrategy;
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.Size;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 涓汉淇℃伅涓氬姟澶勭悊
+ *
+ * @author Michelle.Chung
+ */
+
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class SysUserProfileBo extends BaseEntity {
+
+    /**
+     * 鐢ㄦ埛ID
+     */
+    private Long userId;
+
+    /**
+     * 鐢ㄦ埛鏄电О
+     */
+    @Xss(message = "鐢ㄦ埛鏄电О涓嶈兘鍖呭惈鑴氭湰瀛楃")
+    @Size(min = 0, max = 30, message = "鐢ㄦ埛鏄电О闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
+    private String nickName;
+
+    /**
+     * 鐢ㄦ埛閭
+     */
+    @Sensitive(strategy = SensitiveStrategy.EMAIL)
+    @Email(message = "閭鏍煎紡涓嶆纭�")
+    @Size(min = 0, max = 50, message = "閭闀垮害涓嶈兘瓒呰繃{max}涓瓧绗�")
+    private String email;
+
+    /**
+     * 鎵嬫満鍙风爜
+     */
+    @Sensitive(strategy = SensitiveStrategy.PHONE)
+    private String phonenumber;
+
+    /**
+     * 鐢ㄦ埛鎬у埆锛�0鐢� 1濂� 2鏈煡锛�
+     */
+    private String sex;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/AvatarVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/AvatarVo.java
new file mode 100644
index 0000000..46c020b
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/AvatarVo.java
@@ -0,0 +1,18 @@
+package org.dromara.system.domain.vo;
+
+import lombok.Data;
+
+/**
+ * 鐢ㄦ埛澶村儚淇℃伅
+ *
+ * @author Michelle.Chung
+ */
+@Data
+public class AvatarVo {
+
+    /**
+     * 澶村儚鍦板潃
+     */
+    private String imgUrl;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/CacheListInfoVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/CacheListInfoVo.java
new file mode 100644
index 0000000..f827cba
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/CacheListInfoVo.java
@@ -0,0 +1,23 @@
+package org.dromara.system.domain.vo;
+
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * 缂撳瓨鐩戞帶鍒楄〃淇℃伅
+ *
+ * @author Michelle.Chung
+ */
+@Data
+public class CacheListInfoVo {
+
+    private Properties info;
+
+    private Long dbSize;
+
+    private List<Map<String, String>> commandStats;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/DeptTreeSelectVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/DeptTreeSelectVo.java
new file mode 100644
index 0000000..6f7db28
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/DeptTreeSelectVo.java
@@ -0,0 +1,26 @@
+package org.dromara.system.domain.vo;
+
+import cn.hutool.core.lang.tree.Tree;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 瑙掕壊閮ㄩ棬鍒楄〃鏍戜俊鎭�
+ *
+ * @author Michelle.Chung
+ */
+@Data
+public class DeptTreeSelectVo {
+
+    /**
+     * 閫変腑閮ㄩ棬鍒楄〃
+     */
+    private List<Long> checkedKeys;
+
+    /**
+     * 涓嬫媺鏍戠粨鏋勫垪琛�
+     */
+    private List<Tree<Long>> depts;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/MenuTreeSelectVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/MenuTreeSelectVo.java
new file mode 100644
index 0000000..0724538
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/MenuTreeSelectVo.java
@@ -0,0 +1,26 @@
+package org.dromara.system.domain.vo;
+
+import cn.hutool.core.lang.tree.Tree;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 瑙掕壊鑿滃崟鍒楄〃鏍戜俊鎭�
+ *
+ * @author Michelle.Chung
+ */
+@Data
+public class MenuTreeSelectVo {
+
+    /**
+     * 閫変腑鑿滃崟鍒楄〃
+     */
+    private List<Long> checkedKeys;
+
+    /**
+     * 鑿滃崟涓嬫媺鏍戠粨鏋勫垪琛�
+     */
+    private List<Tree<Long>> menus;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/MetaVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/MetaVo.java
new file mode 100644
index 0000000..f720cd7
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/MetaVo.java
@@ -0,0 +1,61 @@
+package org.dromara.system.domain.vo;
+
+import org.dromara.common.core.utils.StringUtils;
+import lombok.Data;
+
+/**
+ * 璺敱鏄剧ず淇℃伅
+ *
+ * @author ruoyi
+ */
+
+@Data
+public class MetaVo {
+
+    /**
+     * 璁剧疆璇ヨ矾鐢卞湪渚ц竟鏍忓拰闈㈠寘灞戜腑灞曠ず鐨勫悕瀛�
+     */
+    private String title;
+
+    /**
+     * 璁剧疆璇ヨ矾鐢辩殑鍥炬爣锛屽搴旇矾寰剆rc/assets/icons/svg
+     */
+    private String icon;
+
+    /**
+     * 璁剧疆涓簍rue锛屽垯涓嶄細琚� <keep-alive>缂撳瓨
+     */
+    private boolean noCache;
+
+    /**
+     * 鍐呴摼鍦板潃锛坔ttp(s)://寮�澶达級
+     */
+    private String link;
+
+    public MetaVo(String title, String icon) {
+        this.title = title;
+        this.icon = icon;
+    }
+
+    public MetaVo(String title, String icon, boolean noCache) {
+        this.title = title;
+        this.icon = icon;
+        this.noCache = noCache;
+    }
+
+    public MetaVo(String title, String icon, String link) {
+        this.title = title;
+        this.icon = icon;
+        this.link = link;
+    }
+
+    public MetaVo(String title, String icon, boolean noCache, String link) {
+        this.title = title;
+        this.icon = icon;
+        this.noCache = noCache;
+        if (StringUtils.ishttp(link)) {
+            this.link = link;
+        }
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/ProfileVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/ProfileVo.java
new file mode 100644
index 0000000..c047651
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/ProfileVo.java
@@ -0,0 +1,29 @@
+package org.dromara.system.domain.vo;
+
+import lombok.Data;
+
+/**
+ * 鐢ㄦ埛涓汉淇℃伅
+ *
+ * @author Michelle.Chung
+ */
+@Data
+public class ProfileVo {
+
+    /**
+     * 鐢ㄦ埛淇℃伅
+     */
+    private SysUserVo user;
+
+    /**
+     * 鐢ㄦ埛鎵�灞炶鑹茬粍
+     */
+    private String roleGroup;
+
+    /**
+     * 鐢ㄦ埛鎵�灞炲矖浣嶇粍
+     */
+    private String postGroup;
+
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/RouterVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/RouterVo.java
new file mode 100644
index 0000000..0d576ef
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/RouterVo.java
@@ -0,0 +1,62 @@
+package org.dromara.system.domain.vo;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 璺敱閰嶇疆淇℃伅
+ *
+ * @author Lion Li
+ */
+@Data
+@JsonInclude(JsonInclude.Include.NON_EMPTY)
+public class RouterVo {
+
+    /**
+     * 璺敱鍚嶅瓧
+     */
+    private String name;
+
+    /**
+     * 璺敱鍦板潃
+     */
+    private String path;
+
+    /**
+     * 鏄惁闅愯棌璺敱锛屽綋璁剧疆 true 鐨勬椂鍊欒璺敱涓嶄細鍐嶄晶杈规爮鍑虹幇
+     */
+    private boolean hidden;
+
+    /**
+     * 閲嶅畾鍚戝湴鍧�锛屽綋璁剧疆 noRedirect 鐨勬椂鍊欒璺敱鍦ㄩ潰鍖呭睉瀵艰埅涓笉鍙鐐瑰嚮
+     */
+    private String redirect;
+
+    /**
+     * 缁勪欢鍦板潃
+     */
+    private String component;
+
+    /**
+     * 璺敱鍙傛暟锛氬 {"id": 1, "name": "ry"}
+     */
+    private String query;
+
+    /**
+     * 褰撲綘涓�涓矾鐢变笅闈㈢殑 children 澹版槑鐨勮矾鐢卞ぇ浜�1涓椂锛岃嚜鍔ㄤ細鍙樻垚宓屽鐨勬ā寮�--濡傜粍浠堕〉闈�
+     */
+    private Boolean alwaysShow;
+
+    /**
+     * 鍏朵粬鍏冪礌
+     */
+    private MetaVo meta;
+
+    /**
+     * 瀛愯矾鐢�
+     */
+    private List<RouterVo> children;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysConfigVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysConfigVo.java
new file mode 100644
index 0000000..f896000
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysConfigVo.java
@@ -0,0 +1,72 @@
+package org.dromara.system.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import org.dromara.system.domain.SysConfig;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 鍙傛暟閰嶇疆瑙嗗浘瀵硅薄 sys_config
+ *
+ * @author Michelle.Chung
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = SysConfig.class)
+public class SysConfigVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鍙傛暟涓婚敭
+     */
+    @ExcelProperty(value = "鍙傛暟涓婚敭")
+    private Long configId;
+
+    /**
+     * 鍙傛暟鍚嶇О
+     */
+    @ExcelProperty(value = "鍙傛暟鍚嶇О")
+    private String configName;
+
+    /**
+     * 鍙傛暟閿悕
+     */
+    @ExcelProperty(value = "鍙傛暟閿悕")
+    private String configKey;
+
+    /**
+     * 鍙傛暟閿��
+     */
+    @ExcelProperty(value = "鍙傛暟閿��")
+    private String configValue;
+
+    /**
+     * 绯荤粺鍐呯疆锛圷鏄� N鍚︼級
+     */
+    @ExcelProperty(value = "绯荤粺鍐呯疆", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_yes_no")
+    private String configType;
+
+    /**
+     * 澶囨敞
+     */
+    @ExcelProperty(value = "澶囨敞")
+    private String remark;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @ExcelProperty(value = "鍒涘缓鏃堕棿")
+    private Date createTime;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysDeptVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysDeptVo.java
new file mode 100644
index 0000000..e09d67e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysDeptVo.java
@@ -0,0 +1,91 @@
+package org.dromara.system.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import org.dromara.system.domain.SysDept;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 閮ㄩ棬瑙嗗浘瀵硅薄 sys_dept
+ *
+ * @author Michelle.Chung
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = SysDept.class)
+public class SysDeptVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 閮ㄩ棬id
+     */
+    @ExcelProperty(value = "閮ㄩ棬id")
+    private Long deptId;
+
+    /**
+     * 鐖堕儴闂╥d
+     */
+    private Long parentId;
+
+    /**
+     * 鐖堕儴闂ㄥ悕绉�
+     */
+    private String parentName;
+
+    /**
+     * 绁栫骇鍒楄〃
+     */
+    private String ancestors;
+
+    /**
+     * 閮ㄩ棬鍚嶇О
+     */
+    @ExcelProperty(value = "閮ㄩ棬鍚嶇О")
+    private String deptName;
+
+    /**
+     * 鏄剧ず椤哄簭
+     */
+    private Integer orderNum;
+
+    /**
+     * 璐熻矗浜�
+     */
+    @ExcelProperty(value = "璐熻矗浜�")
+    private String leader;
+
+    /**
+     * 鑱旂郴鐢佃瘽
+     */
+    @ExcelProperty(value = "鑱旂郴鐢佃瘽")
+    private String phone;
+
+    /**
+     * 閭
+     */
+    @ExcelProperty(value = "閭")
+    private String email;
+
+    /**
+     * 閮ㄩ棬鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    @ExcelProperty(value = "閮ㄩ棬鐘舵��", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_normal_disable")
+    private String status;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @ExcelProperty(value = "鍒涘缓鏃堕棿")
+    private Date createTime;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysDictDataVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysDictDataVo.java
new file mode 100644
index 0000000..d058d5e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysDictDataVo.java
@@ -0,0 +1,95 @@
+package org.dromara.system.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import org.dromara.system.domain.SysDictData;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 瀛楀吀鏁版嵁瑙嗗浘瀵硅薄 sys_dict_data
+ *
+ * @author Michelle.Chung
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = SysDictData.class)
+public class SysDictDataVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 瀛楀吀缂栫爜
+     */
+    @ExcelProperty(value = "瀛楀吀缂栫爜")
+    private Long dictCode;
+
+    /**
+     * 瀛楀吀鎺掑簭
+     */
+    @ExcelProperty(value = "瀛楀吀鎺掑簭")
+    private Integer dictSort;
+
+    /**
+     * 瀛楀吀鏍囩
+     */
+    @ExcelProperty(value = "瀛楀吀鏍囩")
+    private String dictLabel;
+
+    /**
+     * 瀛楀吀閿��
+     */
+    @ExcelProperty(value = "瀛楀吀閿��")
+    private String dictValue;
+
+    /**
+     * 瀛楀吀绫诲瀷
+     */
+    @ExcelProperty(value = "瀛楀吀绫诲瀷")
+    private String dictType;
+
+    /**
+     * 鏍峰紡灞炴�э紙鍏朵粬鏍峰紡鎵╁睍锛�
+     */
+    private String cssClass;
+
+    /**
+     * 琛ㄦ牸鍥炴樉鏍峰紡
+     */
+    private String listClass;
+
+    /**
+     * 鏄惁榛樿锛圷鏄� N鍚︼級
+     */
+    @ExcelProperty(value = "鏄惁榛樿", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_yes_no")
+    private String isDefault;
+
+    /**
+     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    @ExcelProperty(value = "鐘舵��", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_normal_disable")
+    private String status;
+
+    /**
+     * 澶囨敞
+     */
+    @ExcelProperty(value = "澶囨敞")
+    private String remark;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @ExcelProperty(value = "鍒涘缓鏃堕棿")
+    private Date createTime;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysDictTypeVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysDictTypeVo.java
new file mode 100644
index 0000000..2cac4a2
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysDictTypeVo.java
@@ -0,0 +1,66 @@
+package org.dromara.system.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import org.dromara.system.domain.SysDictType;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 瀛楀吀绫诲瀷瑙嗗浘瀵硅薄 sys_dict_type
+ *
+ * @author Michelle.Chung
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = SysDictType.class)
+public class SysDictTypeVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 瀛楀吀涓婚敭
+     */
+    @ExcelProperty(value = "瀛楀吀涓婚敭")
+    private Long dictId;
+
+    /**
+     * 瀛楀吀鍚嶇О
+     */
+    @ExcelProperty(value = "瀛楀吀鍚嶇О")
+    private String dictName;
+
+    /**
+     * 瀛楀吀绫诲瀷
+     */
+    @ExcelProperty(value = "瀛楀吀绫诲瀷")
+    private String dictType;
+
+    /**
+     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    @ExcelProperty(value = "鐘舵��", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_normal_disable")
+    private String status;
+
+    /**
+     * 澶囨敞
+     */
+    @ExcelProperty(value = "澶囨敞")
+    private String remark;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @ExcelProperty(value = "鍒涘缓鏃堕棿")
+    private Date createTime;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysLogininforVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysLogininforVo.java
new file mode 100644
index 0000000..cf9720e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysLogininforVo.java
@@ -0,0 +1,93 @@
+package org.dromara.system.domain.vo;
+
+import java.util.Date;
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import org.dromara.system.domain.SysLogininfor;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+
+
+/**
+ * 绯荤粺璁块棶璁板綍瑙嗗浘瀵硅薄 sys_logininfor
+ *
+ * @author Michelle.Chung
+ * @date 2023-02-07
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = SysLogininfor.class)
+public class SysLogininforVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 璁块棶ID
+     */
+    @ExcelProperty(value = "搴忓彿")
+    private Long infoId;
+
+    /**
+     * 绉熸埛缂栧彿
+     */
+    private String tenantId;
+
+    /**
+     * 鐢ㄦ埛璐﹀彿
+     */
+    @ExcelProperty(value = "鐢ㄦ埛璐﹀彿")
+    private String userName;
+
+    /**
+     * 鐧诲綍鐘舵�侊紙0鎴愬姛 1澶辫触锛�
+     */
+    @ExcelProperty(value = "鐧诲綍鐘舵��", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_common_status")
+    private String status;
+
+    /**
+     * 鐧诲綍IP鍦板潃
+     */
+    @ExcelProperty(value = "鐧诲綍鍦板潃")
+    private String ipaddr;
+
+    /**
+     * 鐧诲綍鍦扮偣
+     */
+    @ExcelProperty(value = "鐧诲綍鍦扮偣")
+    private String loginLocation;
+
+    /**
+     * 娴忚鍣ㄧ被鍨�
+     */
+    @ExcelProperty(value = "娴忚鍣�")
+    private String browser;
+
+    /**
+     * 鎿嶄綔绯荤粺
+     */
+    @ExcelProperty(value = "鎿嶄綔绯荤粺")
+    private String os;
+
+
+    /**
+     * 鎻愮ず娑堟伅
+     */
+    @ExcelProperty(value = "鎻愮ず娑堟伅")
+    private String msg;
+
+    /**
+     * 璁块棶鏃堕棿
+     */
+    @ExcelProperty(value = "璁块棶鏃堕棿")
+    private Date loginTime;
+
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysMenuVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysMenuVo.java
new file mode 100644
index 0000000..5214a33
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysMenuVo.java
@@ -0,0 +1,116 @@
+package org.dromara.system.domain.vo;
+
+import org.dromara.system.domain.SysMenu;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+
+/**
+ * 鑿滃崟鏉冮檺瑙嗗浘瀵硅薄 sys_menu
+ *
+ * @author Michelle.Chung
+ */
+@Data
+@AutoMapper(target = SysMenu.class)
+public class SysMenuVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鑿滃崟ID
+     */
+    private Long menuId;
+
+    /**
+     * 鑿滃崟鍚嶇О
+     */
+    private String menuName;
+
+    /**
+     * 鐖惰彍鍗旾D
+     */
+    private Long parentId;
+
+    /**
+     * 鏄剧ず椤哄簭
+     */
+    private Integer orderNum;
+
+    /**
+     * 璺敱鍦板潃
+     */
+    private String path;
+
+    /**
+     * 缁勪欢璺緞
+     */
+    private String component;
+
+    /**
+     * 璺敱鍙傛暟
+     */
+    private String queryParam;
+
+    /**
+     * 鏄惁涓哄閾撅紙0鏄� 1鍚︼級
+     */
+    private String isFrame;
+
+    /**
+     * 鏄惁缂撳瓨锛�0缂撳瓨 1涓嶇紦瀛橈級
+     */
+    private String isCache;
+
+    /**
+     * 鑿滃崟绫诲瀷锛圡鐩綍 C鑿滃崟 F鎸夐挳锛�
+     */
+    private String menuType;
+
+    /**
+     * 鏄剧ず鐘舵�侊紙0鏄剧ず 1闅愯棌锛�
+     */
+    private String visible;
+
+    /**
+     * 鑿滃崟鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    private String status;
+
+    /**
+     * 鏉冮檺鏍囪瘑
+     */
+    private String perms;
+
+    /**
+     * 鑿滃崟鍥炬爣
+     */
+    private String icon;
+
+    /**
+     * 鍒涘缓閮ㄩ棬
+     */
+    private Long createDept;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    private Date createTime;
+
+    /**
+     * 瀛愯彍鍗�
+     */
+    private List<SysMenuVo> children = new ArrayList<>();
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysNoticeVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysNoticeVo.java
new file mode 100644
index 0000000..afe7367
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysNoticeVo.java
@@ -0,0 +1,73 @@
+package org.dromara.system.domain.vo;
+
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.common.translation.constant.TransConstant;
+import org.dromara.system.domain.SysNotice;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 閫氱煡鍏憡瑙嗗浘瀵硅薄 sys_notice
+ *
+ * @author Michelle.Chung
+ */
+@Data
+@AutoMapper(target = SysNotice.class)
+public class SysNoticeVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鍏憡ID
+     */
+    private Long noticeId;
+
+    /**
+     * 鍏憡鏍囬
+     */
+    private String noticeTitle;
+
+    /**
+     * 鍏憡绫诲瀷锛�1閫氱煡 2鍏憡锛�
+     */
+    private String noticeType;
+
+    /**
+     * 鍏憡鍐呭
+     */
+    private String noticeContent;
+
+    /**
+     * 鍏憡鐘舵�侊紙0姝e父 1鍏抽棴锛�
+     */
+    private String status;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+    /**
+     * 鍒涘缓鑰�
+     */
+    private Long createBy;
+
+    /**
+     * 鍒涘缓浜哄悕绉�
+     */
+    @Translation(type = TransConstant.USER_ID_TO_NAME, mapper = "createBy")
+    private String createByName;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    private Date createTime;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysOperLogVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysOperLogVo.java
new file mode 100644
index 0000000..d9eb71d
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysOperLogVo.java
@@ -0,0 +1,144 @@
+package org.dromara.system.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import org.dromara.system.domain.SysOperLog;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 鎿嶄綔鏃ュ織璁板綍瑙嗗浘瀵硅薄 sys_oper_log
+ *
+ * @author Michelle.Chung
+ * @date 2023-02-07
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = SysOperLog.class)
+public class SysOperLogVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鏃ュ織涓婚敭
+     */
+    @ExcelProperty(value = "鏃ュ織涓婚敭")
+    private Long operId;
+
+    /**
+     * 绉熸埛缂栧彿
+     */
+    private String tenantId;
+
+    /**
+     * 妯″潡鏍囬
+     */
+    @ExcelProperty(value = "鎿嶄綔妯″潡")
+    private String title;
+
+    /**
+     * 涓氬姟绫诲瀷锛�0鍏跺畠 1鏂板 2淇敼 3鍒犻櫎锛�
+     */
+    @ExcelProperty(value = "涓氬姟绫诲瀷", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_oper_type")
+    private Integer businessType;
+
+    /**
+     * 涓氬姟绫诲瀷鏁扮粍
+     */
+    private Integer[] businessTypes;
+
+    /**
+     * 鏂规硶鍚嶇О
+     */
+    @ExcelProperty(value = "璇锋眰鏂规硶")
+    private String method;
+
+    /**
+     * 璇锋眰鏂瑰紡
+     */
+    @ExcelProperty(value = "璇锋眰鏂瑰紡")
+    private String requestMethod;
+
+    /**
+     * 鎿嶄綔绫诲埆锛�0鍏跺畠 1鍚庡彴鐢ㄦ埛 2鎵嬫満绔敤鎴凤級
+     */
+    @ExcelProperty(value = "鎿嶄綔绫诲埆", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=鍏跺畠,1=鍚庡彴鐢ㄦ埛,2=鎵嬫満绔敤鎴�")
+    private Integer operatorType;
+
+    /**
+     * 鎿嶄綔浜哄憳
+     */
+    @ExcelProperty(value = "鎿嶄綔浜哄憳")
+    private String operName;
+
+    /**
+     * 閮ㄩ棬鍚嶇О
+     */
+    @ExcelProperty(value = "閮ㄩ棬鍚嶇О")
+    private String deptName;
+
+    /**
+     * 璇锋眰URL
+     */
+    @ExcelProperty(value = "璇锋眰鍦板潃")
+    private String operUrl;
+
+    /**
+     * 涓绘満鍦板潃
+     */
+    @ExcelProperty(value = "鎿嶄綔鍦板潃")
+    private String operIp;
+
+    /**
+     * 鎿嶄綔鍦扮偣
+     */
+    @ExcelProperty(value = "鎿嶄綔鍦扮偣")
+    private String operLocation;
+
+    /**
+     * 璇锋眰鍙傛暟
+     */
+    @ExcelProperty(value = "璇锋眰鍙傛暟")
+    private String operParam;
+
+    /**
+     * 杩斿洖鍙傛暟
+     */
+    @ExcelProperty(value = "杩斿洖鍙傛暟")
+    private String jsonResult;
+
+    /**
+     * 鎿嶄綔鐘舵�侊紙0姝e父 1寮傚父锛�
+     */
+    @ExcelProperty(value = "鐘舵��", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_common_status")
+    private Integer status;
+
+    /**
+     * 閿欒娑堟伅
+     */
+    @ExcelProperty(value = "閿欒娑堟伅")
+    private String errorMsg;
+
+    /**
+     * 鎿嶄綔鏃堕棿
+     */
+    @ExcelProperty(value = "鎿嶄綔鏃堕棿")
+    private Date operTime;
+
+    /**
+     * 娑堣�楁椂闂�
+     */
+    @ExcelProperty(value = "娑堣�楁椂闂�")
+    private Long costTime;
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysOssConfigVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysOssConfigVo.java
new file mode 100644
index 0000000..b88ec40
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysOssConfigVo.java
@@ -0,0 +1,97 @@
+package org.dromara.system.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import org.dromara.system.domain.SysOssConfig;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+
+/**
+ * 瀵硅薄瀛樺偍閰嶇疆瑙嗗浘瀵硅薄 sys_oss_config
+ *
+ * @author Lion Li
+ * @author 瀛よ垷鐑熼洦
+ * @date 2021-08-13
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = SysOssConfig.class)
+public class SysOssConfigVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 涓诲缓
+     */
+    private Long ossConfigId;
+
+    /**
+     * 閰嶇疆key
+     */
+    private String configKey;
+
+    /**
+     * accessKey
+     */
+    private String accessKey;
+
+    /**
+     * 绉橀挜
+     */
+    private String secretKey;
+
+    /**
+     * 妗跺悕绉�
+     */
+    private String bucketName;
+
+    /**
+     * 鍓嶇紑
+     */
+    private String prefix;
+
+    /**
+     * 璁块棶绔欑偣
+     */
+    private String endpoint;
+
+    /**
+     * 鑷畾涔夊煙鍚�
+     */
+    private String domain;
+
+    /**
+     * 鏄惁https锛圷=鏄�,N=鍚︼級
+     */
+    private String isHttps;
+
+    /**
+     * 鍩�
+     */
+    private String region;
+
+    /**
+     * 鏄惁榛樿锛�0=鏄�,1=鍚︼級
+     */
+    private String status;
+
+    /**
+     * 鎵╁睍瀛楁
+     */
+    private String ext1;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+    /**
+     * 妗舵潈闄愮被鍨�(0private 1public 2custom)
+     */
+    private String accessPolicy;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysOssUploadVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysOssUploadVo.java
new file mode 100644
index 0000000..11e0ff8
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysOssUploadVo.java
@@ -0,0 +1,28 @@
+package org.dromara.system.domain.vo;
+
+import lombok.Data;
+
+/**
+ * 涓婁紶瀵硅薄淇℃伅
+ *
+ * @author Michelle.Chung
+ */
+@Data
+public class SysOssUploadVo {
+
+    /**
+     * URL鍦板潃
+     */
+    private String url;
+
+    /**
+     * 鏂囦欢鍚�
+     */
+    private String fileName;
+
+    /**
+     * 瀵硅薄瀛樺偍涓婚敭
+     */
+    private String ossId;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysOssVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysOssVo.java
new file mode 100644
index 0000000..8d5c429
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysOssVo.java
@@ -0,0 +1,72 @@
+package org.dromara.system.domain.vo;
+
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.common.translation.constant.TransConstant;
+import org.dromara.system.domain.SysOss;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * OSS瀵硅薄瀛樺偍瑙嗗浘瀵硅薄 sys_oss
+ *
+ * @author Lion Li
+ */
+@Data
+@AutoMapper(target = SysOss.class)
+public class SysOssVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 瀵硅薄瀛樺偍涓婚敭
+     */
+    private Long ossId;
+
+    /**
+     * 鏂囦欢鍚�
+     */
+    private String fileName;
+
+    /**
+     * 鍘熷悕
+     */
+    private String originalName;
+
+    /**
+     * 鏂囦欢鍚庣紑鍚�
+     */
+    private String fileSuffix;
+
+    /**
+     * URL鍦板潃
+     */
+    private String url;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    private Date createTime;
+
+    /**
+     * 涓婁紶浜�
+     */
+    private Long createBy;
+
+    /**
+     * 涓婁紶浜哄悕绉�
+     */
+    @Translation(type = TransConstant.USER_ID_TO_NAME, mapper = "createBy")
+    private String createByName;
+
+    /**
+     * 鏈嶅姟鍟�
+     */
+    private String service;
+
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysPostVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysPostVo.java
new file mode 100644
index 0000000..3e6c6a8
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysPostVo.java
@@ -0,0 +1,73 @@
+package org.dromara.system.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import org.dromara.system.domain.SysPost;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 宀椾綅淇℃伅瑙嗗浘瀵硅薄 sys_post
+ *
+ * @author Michelle.Chung
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = SysPost.class)
+public class SysPostVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 宀椾綅ID
+     */
+    @ExcelProperty(value = "宀椾綅搴忓彿")
+    private Long postId;
+
+    /**
+     * 宀椾綅缂栫爜
+     */
+    @ExcelProperty(value = "宀椾綅缂栫爜")
+    private String postCode;
+
+    /**
+     * 宀椾綅鍚嶇О
+     */
+    @ExcelProperty(value = "宀椾綅鍚嶇О")
+    private String postName;
+
+    /**
+     * 鏄剧ず椤哄簭
+     */
+    @ExcelProperty(value = "宀椾綅鎺掑簭")
+    private Integer postSort;
+
+    /**
+     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    @ExcelProperty(value = "鐘舵��", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_normal_disable")
+    private String status;
+
+    /**
+     * 澶囨敞
+     */
+    @ExcelProperty(value = "澶囨敞")
+    private String remark;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @ExcelProperty(value = "鍒涘缓鏃堕棿")
+    private Date createTime;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysRoleVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysRoleVo.java
new file mode 100644
index 0000000..1e5cd9e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysRoleVo.java
@@ -0,0 +1,100 @@
+package org.dromara.system.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import org.dromara.common.core.constant.UserConstants;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import org.dromara.system.domain.SysRole;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 瑙掕壊淇℃伅瑙嗗浘瀵硅薄 sys_role
+ *
+ * @author Michelle.Chung
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = SysRole.class)
+public class SysRoleVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 瑙掕壊ID
+     */
+    @ExcelProperty(value = "瑙掕壊搴忓彿")
+    private Long roleId;
+
+    /**
+     * 瑙掕壊鍚嶇О
+     */
+    @ExcelProperty(value = "瑙掕壊鍚嶇О")
+    private String roleName;
+
+    /**
+     * 瑙掕壊鏉冮檺瀛楃涓�
+     */
+    @ExcelProperty(value = "瑙掕壊鏉冮檺")
+    private String roleKey;
+
+    /**
+     * 鏄剧ず椤哄簭
+     */
+    @ExcelProperty(value = "瑙掕壊鎺掑簭")
+    private Integer roleSort;
+
+    /**
+     * 鏁版嵁鑼冨洿锛�1锛氬叏閮ㄦ暟鎹潈闄� 2锛氳嚜瀹氭暟鎹潈闄� 3锛氭湰閮ㄩ棬鏁版嵁鏉冮檺 4锛氭湰閮ㄩ棬鍙婁互涓嬫暟鎹潈闄愶級
+     */
+    @ExcelProperty(value = "鏁版嵁鑼冨洿", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "1=鎵�鏈夋暟鎹潈闄�,2=鑷畾涔夋暟鎹潈闄�,3=鏈儴闂ㄦ暟鎹潈闄�,4=鏈儴闂ㄥ強浠ヤ笅鏁版嵁鏉冮檺,5=浠呮湰浜烘暟鎹潈闄�")
+    private String dataScope;
+
+    /**
+     * 鑿滃崟鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�
+     */
+    @ExcelProperty(value = "鑿滃崟鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�")
+    private Boolean menuCheckStrictly;
+
+    /**
+     * 閮ㄩ棬鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�
+     */
+    @ExcelProperty(value = "閮ㄩ棬鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�")
+    private Boolean deptCheckStrictly;
+
+    /**
+     * 瑙掕壊鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    @ExcelProperty(value = "瑙掕壊鐘舵��", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_normal_disable")
+    private String status;
+
+    /**
+     * 澶囨敞
+     */
+    @ExcelProperty(value = "澶囨敞")
+    private String remark;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @ExcelProperty(value = "鍒涘缓鏃堕棿")
+    private Date createTime;
+
+    /**
+     * 鐢ㄦ埛鏄惁瀛樺湪姝よ鑹叉爣璇� 榛樿涓嶅瓨鍦�
+     */
+    private boolean flag = false;
+
+    public boolean isSuperAdmin() {
+        return UserConstants.SUPER_ADMIN_ID.equals(this.roleId);
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysTenantPackageVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysTenantPackageVo.java
new file mode 100644
index 0000000..070334b
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysTenantPackageVo.java
@@ -0,0 +1,66 @@
+package org.dromara.system.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import org.dromara.system.domain.SysTenantPackage;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+
+/**
+ * 绉熸埛濂楅瑙嗗浘瀵硅薄 sys_tenant_package
+ *
+ * @author Michelle.Chung
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = SysTenantPackage.class)
+public class SysTenantPackageVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 绉熸埛濂楅id
+     */
+    @ExcelProperty(value = "绉熸埛濂楅id")
+    private Long packageId;
+
+    /**
+     * 濂楅鍚嶇О
+     */
+    @ExcelProperty(value = "濂楅鍚嶇О")
+    private String packageName;
+
+    /**
+     * 鍏宠仈鑿滃崟id
+     */
+    @ExcelProperty(value = "鍏宠仈鑿滃崟id")
+    private String menuIds;
+
+    /**
+     * 澶囨敞
+     */
+    @ExcelProperty(value = "澶囨敞")
+    private String remark;
+
+    /**
+     * 鑿滃崟鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�
+     */
+    @ExcelProperty(value = "鑿滃崟鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�")
+    private Boolean menuCheckStrictly;
+
+    /**
+     * 鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    @ExcelProperty(value = "鐘舵��", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=姝e父,1=鍋滅敤")
+    private String status;
+
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysTenantVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysTenantVo.java
new file mode 100644
index 0000000..6a45315
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysTenantVo.java
@@ -0,0 +1,115 @@
+package org.dromara.system.domain.vo;
+
+import java.util.Date;
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import org.dromara.system.domain.SysTenant;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+
+/**
+ * 绉熸埛瑙嗗浘瀵硅薄 sys_tenant
+ *
+ * @author Michelle.Chung
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = SysTenant.class)
+public class SysTenantVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * id
+     */
+    @ExcelProperty(value = "id")
+    private Long id;
+
+    /**
+     * 绉熸埛缂栧彿
+     */
+    @ExcelProperty(value = "绉熸埛缂栧彿")
+    private String tenantId;
+
+    /**
+     * 鑱旂郴浜�
+     */
+    @ExcelProperty(value = "鑱旂郴浜�")
+    private String contactUserName;
+
+    /**
+     * 鑱旂郴鐢佃瘽
+     */
+    @ExcelProperty(value = "鑱旂郴鐢佃瘽")
+    private String contactPhone;
+
+    /**
+     * 浼佷笟鍚嶇О
+     */
+    @ExcelProperty(value = "浼佷笟鍚嶇О")
+    private String companyName;
+
+    /**
+     * 缁熶竴绀句細淇$敤浠g爜
+     */
+    @ExcelProperty(value = "缁熶竴绀句細淇$敤浠g爜")
+    private String licenseNumber;
+
+    /**
+     * 鍦板潃
+     */
+    @ExcelProperty(value = "鍦板潃")
+    private String address;
+
+    /**
+     * 鍩熷悕
+     */
+    @ExcelProperty(value = "鍩熷悕")
+    private String domain;
+
+    /**
+     * 浼佷笟绠�浠�
+     */
+    @ExcelProperty(value = "浼佷笟绠�浠�")
+    private String intro;
+
+    /**
+     * 澶囨敞
+     */
+    @ExcelProperty(value = "澶囨敞")
+    private String remark;
+
+    /**
+     * 绉熸埛濂楅缂栧彿
+     */
+    @ExcelProperty(value = "绉熸埛濂楅缂栧彿")
+    private Long packageId;
+
+    /**
+     * 杩囨湡鏃堕棿
+     */
+    @ExcelProperty(value = "杩囨湡鏃堕棿")
+    private Date expireTime;
+
+    /**
+     * 鐢ㄦ埛鏁伴噺锛�-1涓嶉檺鍒讹級
+     */
+    @ExcelProperty(value = "鐢ㄦ埛鏁伴噺")
+    private Long accountCount;
+
+    /**
+     * 绉熸埛鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    @ExcelProperty(value = "绉熸埛鐘舵��", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=姝e父,1=鍋滅敤")
+    private String status;
+
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserExportVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserExportVo.java
new file mode 100644
index 0000000..21b1efb
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserExportVo.java
@@ -0,0 +1,99 @@
+package org.dromara.system.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import io.github.linpeilie.annotations.ReverseAutoMapping;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 鐢ㄦ埛瀵硅薄瀵煎嚭VO
+ *
+ * @author Lion Li
+ */
+
+@Data
+@NoArgsConstructor
+@AutoMapper(target = SysUserVo.class, convertGenerate = false)
+public class SysUserExportVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鐢ㄦ埛ID
+     */
+    @ExcelProperty(value = "鐢ㄦ埛搴忓彿")
+    private Long userId;
+
+    /**
+     * 鐢ㄦ埛璐﹀彿
+     */
+    @ExcelProperty(value = "鐧诲綍鍚嶇О")
+    private String userName;
+
+    /**
+     * 鐢ㄦ埛鏄电О
+     */
+    @ExcelProperty(value = "鐢ㄦ埛鍚嶇О")
+    private String nickName;
+
+    /**
+     * 鐢ㄦ埛閭
+     */
+    @ExcelProperty(value = "鐢ㄦ埛閭")
+    private String email;
+
+    /**
+     * 鎵嬫満鍙风爜
+     */
+    @ExcelProperty(value = "鎵嬫満鍙风爜")
+    private String phonenumber;
+
+    /**
+     * 鐢ㄦ埛鎬у埆
+     */
+    @ExcelProperty(value = "鐢ㄦ埛鎬у埆", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_user_sex")
+    private String sex;
+
+    /**
+     * 甯愬彿鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    @ExcelProperty(value = "甯愬彿鐘舵��", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_normal_disable")
+    private String status;
+
+    /**
+     * 鏈�鍚庣櫥褰旾P
+     */
+    @ExcelProperty(value = "鏈�鍚庣櫥褰旾P")
+    private String loginIp;
+
+    /**
+     * 鏈�鍚庣櫥褰曟椂闂�
+     */
+    @ExcelProperty(value = "鏈�鍚庣櫥褰曟椂闂�")
+    private Date loginDate;
+
+    /**
+     * 閮ㄩ棬鍚嶇О
+     */
+    @ReverseAutoMapping(target = "deptName", source = "dept.deptName")
+    @ExcelProperty(value = "閮ㄩ棬鍚嶇О")
+    private String deptName;
+
+    /**
+     * 璐熻矗浜�
+     */
+    @ReverseAutoMapping(target = "leader", source = "dept.leader")
+    @ExcelProperty(value = "閮ㄩ棬璐熻矗浜�")
+    private String leader;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserImportVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserImportVo.java
new file mode 100644
index 0000000..c34a23c
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserImportVo.java
@@ -0,0 +1,76 @@
+package org.dromara.system.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 鐢ㄦ埛瀵硅薄瀵煎叆VO
+ *
+ * @author Lion Li
+ */
+
+@Data
+@NoArgsConstructor
+// @Accessors(chain = true) // 瀵煎叆涓嶅厑璁镐娇鐢� 浼氭壘涓嶅埌set鏂规硶
+public class SysUserImportVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鐢ㄦ埛ID
+     */
+    @ExcelProperty(value = "鐢ㄦ埛搴忓彿")
+    private Long userId;
+
+    /**
+     * 閮ㄩ棬ID
+     */
+    @ExcelProperty(value = "閮ㄩ棬缂栧彿")
+    private Long deptId;
+
+    /**
+     * 鐢ㄦ埛璐﹀彿
+     */
+    @ExcelProperty(value = "鐧诲綍鍚嶇О")
+    private String userName;
+
+    /**
+     * 鐢ㄦ埛鏄电О
+     */
+    @ExcelProperty(value = "鐢ㄦ埛鍚嶇О")
+    private String nickName;
+
+    /**
+     * 鐢ㄦ埛閭
+     */
+    @ExcelProperty(value = "鐢ㄦ埛閭")
+    private String email;
+
+    /**
+     * 鎵嬫満鍙风爜
+     */
+    @ExcelProperty(value = "鎵嬫満鍙风爜")
+    private String phonenumber;
+
+    /**
+     * 鐢ㄦ埛鎬у埆
+     */
+    @ExcelProperty(value = "鐢ㄦ埛鎬у埆", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_user_sex")
+    private String sex;
+
+    /**
+     * 甯愬彿鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    @ExcelProperty(value = "甯愬彿鐘舵��", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_normal_disable")
+    private String status;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserInfoVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserInfoVo.java
new file mode 100644
index 0000000..e41355d
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserInfoVo.java
@@ -0,0 +1,40 @@
+package org.dromara.system.domain.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 鐢ㄦ埛淇℃伅
+ *
+ * @author Michelle.Chung
+ */
+@Data
+public class SysUserInfoVo {
+
+    /**
+     * 鐢ㄦ埛淇℃伅
+     */
+    private SysUserVo user;
+
+    /**
+     * 瑙掕壊ID鍒楄〃
+     */
+    private List<Long> roleIds;
+
+    /**
+     * 瑙掕壊鍒楄〃
+     */
+    private List<SysRoleVo> roles;
+
+    /**
+     * 宀椾綅ID鍒楄〃
+     */
+    private List<Long> postIds;
+
+    /**
+     * 宀椾綅鍒楄〃
+     */
+    private List<SysPostVo> posts;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java
new file mode 100644
index 0000000..3faf325
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java
@@ -0,0 +1,137 @@
+package org.dromara.system.domain.vo;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.common.translation.constant.TransConstant;
+import org.dromara.system.domain.SysUser;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+
+/**
+ * 鐢ㄦ埛淇℃伅瑙嗗浘瀵硅薄 sys_user
+ *
+ * @author Michelle.Chung
+ */
+@Data
+@AutoMapper(target = SysUser.class)
+public class SysUserVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鐢ㄦ埛ID
+     */
+    private Long userId;
+
+    /**
+     * 绉熸埛ID
+     */
+    private String tenantId;
+
+    /**
+     * 閮ㄩ棬ID
+     */
+    private Long deptId;
+
+    /**
+     * 鐢ㄦ埛璐﹀彿
+     */
+    private String userName;
+
+    /**
+     * 鐢ㄦ埛鏄电О
+     */
+    private String nickName;
+
+    /**
+     * 鐢ㄦ埛绫诲瀷锛坰ys_user绯荤粺鐢ㄦ埛锛�
+     */
+    private String userType;
+
+    /**
+     * 鐢ㄦ埛閭
+     */
+    private String email;
+
+    /**
+     * 鎵嬫満鍙风爜
+     */
+    private String phonenumber;
+
+    /**
+     * 鐢ㄦ埛鎬у埆锛�0鐢� 1濂� 2鏈煡锛�
+     */
+    private String sex;
+
+    /**
+     * 澶村儚鍦板潃
+     */
+    @Translation(type = TransConstant.OSS_ID_TO_URL)
+    private Long avatar;
+
+    /**
+     * 瀵嗙爜
+     */
+    @JsonIgnore
+    @JsonProperty
+    private String password;
+
+    /**
+     * 甯愬彿鐘舵�侊紙0姝e父 1鍋滅敤锛�
+     */
+    private String status;
+
+    /**
+     * 鏈�鍚庣櫥褰旾P
+     */
+    private String loginIp;
+
+    /**
+     * 鏈�鍚庣櫥褰曟椂闂�
+     */
+    private Date loginDate;
+
+    /**
+     * 澶囨敞
+     */
+    private String remark;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    private Date createTime;
+
+    /**
+     * 閮ㄩ棬瀵硅薄
+     */
+    private SysDeptVo dept;
+
+    /**
+     * 瑙掕壊瀵硅薄
+     */
+    private List<SysRoleVo> roles;
+
+    /**
+     * 瑙掕壊缁�
+     */
+    private Long[] roleIds;
+
+    /**
+     * 宀椾綅缁�
+     */
+    private Long[] postIds;
+
+    /**
+     * 鏁版嵁鏉冮檺 褰撳墠瑙掕壊ID
+     */
+    private Long roleId;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/UserInfoVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/UserInfoVo.java
new file mode 100644
index 0000000..48fa92a
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/UserInfoVo.java
@@ -0,0 +1,30 @@
+package org.dromara.system.domain.vo;
+
+import lombok.Data;
+
+import java.util.Set;
+
+/**
+ * 鐧诲綍鐢ㄦ埛淇℃伅
+ *
+ * @author Michelle.Chung
+ */
+@Data
+public class UserInfoVo {
+
+    /**
+     * 鐢ㄦ埛鍩烘湰淇℃伅
+     */
+    private SysUserVo user;
+
+    /**
+     * 鑿滃崟鏉冮檺
+     */
+    private Set<String> permissions;
+
+    /**
+     * 瑙掕壊鏉冮檺
+     */
+    private Set<String> roles;
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/listener/SysUserImportListener.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/listener/SysUserImportListener.java
new file mode 100644
index 0000000..c703150
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/listener/SysUserImportListener.java
@@ -0,0 +1,119 @@
+package org.dromara.system.listener;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.crypto.digest.BCrypt;
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.ValidatorUtils;
+import org.dromara.common.excel.core.ExcelListener;
+import org.dromara.common.excel.core.ExcelResult;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.system.domain.bo.SysUserBo;
+import org.dromara.system.domain.vo.SysUserImportVo;
+import org.dromara.system.domain.vo.SysUserVo;
+import org.dromara.system.service.ISysConfigService;
+import org.dromara.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 Long operUserId;
+
+    private int successNum = 0;
+    private int failureNum = 0;
+    private final StringBuilder successMsg = new StringBuilder();
+    private final StringBuilder failureMsg = new StringBuilder();
+
+    public SysUserImportListener(Boolean isUpdateSupport) {
+        String initPassword = SpringUtils.getBean(ISysConfigService.class).selectConfigByKey("sys.user.initPassword");
+        this.userService = SpringUtils.getBean(ISysUserService.class);
+        this.password = BCrypt.hashpw(initPassword);
+        this.isUpdateSupport = isUpdateSupport;
+        this.operUserId = LoginHelper.getUserId();
+    }
+
+    @Override
+    public void invoke(SysUserImportVo userVo, AnalysisContext context) {
+        SysUserVo sysUser = this.userService.selectUserByUserName(userVo.getUserName());
+        try {
+            // 楠岃瘉鏄惁瀛樺湪杩欎釜鐢ㄦ埛
+            if (ObjectUtil.isNull(sysUser)) {
+                SysUserBo user = BeanUtil.toBean(userVo, SysUserBo.class);
+                ValidatorUtils.validate(user);
+                user.setPassword(password);
+                user.setCreateBy(operUserId);
+                userService.insertUser(user);
+                successNum++;
+                successMsg.append("<br/>").append(successNum).append("銆佽处鍙� ").append(user.getUserName()).append(" 瀵煎叆鎴愬姛");
+            } else if (isUpdateSupport) {
+                Long userId = sysUser.getUserId();
+                SysUserBo user = BeanUtil.toBean(userVo, SysUserBo.class);
+                user.setUserId(userId);
+                ValidatorUtils.validate(user);
+                userService.checkUserAllowed(user.getUserId());
+                userService.checkUserDataScope(user.getUserId());
+                user.setUpdateBy(operUserId);
+                userService.updateUser(user);
+                successNum++;
+                successMsg.append("<br/>").append(successNum).append("銆佽处鍙� ").append(user.getUserName()).append(" 鏇存柊鎴愬姛");
+            } else {
+                failureNum++;
+                failureMsg.append("<br/>").append(failureNum).append("銆佽处鍙� ").append(sysUser.getUserName()).append(" 宸插瓨鍦�");
+            }
+        } catch (Exception e) {
+            failureNum++;
+            String msg = "<br/>" + failureNum + "銆佽处鍙� " + sysUser.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<>() {
+
+            @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-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysConfigMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysConfigMapper.java
new file mode 100644
index 0000000..0eaaee8
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysConfigMapper.java
@@ -0,0 +1,14 @@
+package org.dromara.system.mapper;
+
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.system.domain.SysConfig;
+import org.dromara.system.domain.vo.SysConfigVo;
+
+/**
+ * 鍙傛暟閰嶇疆 鏁版嵁灞�
+ *
+ * @author Lion Li
+ */
+public interface SysConfigMapper extends BaseMapperPlus<SysConfig, SysConfigVo> {
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysDeptMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysDeptMapper.java
new file mode 100644
index 0000000..45ad77e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysDeptMapper.java
@@ -0,0 +1,46 @@
+package org.dromara.system.mapper;
+
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import org.dromara.common.mybatis.annotation.DataColumn;
+import org.dromara.common.mybatis.annotation.DataPermission;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.system.domain.SysDept;
+import org.dromara.system.domain.vo.SysDeptVo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 閮ㄩ棬绠$悊 鏁版嵁灞�
+ *
+ * @author Lion Li
+ */
+public interface SysDeptMapper extends BaseMapperPlus<SysDept, SysDeptVo> {
+
+    /**
+     * 鏌ヨ閮ㄩ棬绠$悊鏁版嵁
+     *
+     * @param queryWrapper 鏌ヨ鏉′欢
+     * @return 閮ㄩ棬淇℃伅闆嗗悎
+     */
+    @DataPermission({
+        @DataColumn(key = "deptName", value = "dept_id")
+    })
+    List<SysDeptVo> selectDeptList(@Param(Constants.WRAPPER) Wrapper<SysDept> queryWrapper);
+
+    @DataPermission({
+        @DataColumn(key = "deptName", value = "dept_id")
+    })
+    SysDeptVo selectDeptById(Long deptId);
+
+    /**
+     * 鏍规嵁瑙掕壊ID鏌ヨ閮ㄩ棬鏍戜俊鎭�
+     *
+     * @param roleId            瑙掕壊ID
+     * @param deptCheckStrictly 閮ㄩ棬鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�
+     * @return 閫変腑閮ㄩ棬鍒楄〃
+     */
+    List<Long> selectDeptListByRoleId(@Param("roleId") Long roleId, @Param("deptCheckStrictly") boolean deptCheckStrictly);
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysDictDataMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysDictDataMapper.java
new file mode 100644
index 0000000..5c85653
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysDictDataMapper.java
@@ -0,0 +1,25 @@
+package org.dromara.system.mapper;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import org.dromara.common.core.constant.UserConstants;
+import org.dromara.system.domain.SysDictData;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.system.domain.vo.SysDictDataVo;
+
+import java.util.List;
+
+/**
+ * 瀛楀吀琛� 鏁版嵁灞�
+ *
+ * @author Lion Li
+ */
+public interface SysDictDataMapper extends BaseMapperPlus<SysDictData, SysDictDataVo> {
+
+    default List<SysDictDataVo> selectDictDataByType(String dictType) {
+        return selectVoList(
+            new LambdaQueryWrapper<SysDictData>()
+                .eq(SysDictData::getStatus, UserConstants.DICT_NORMAL)
+                .eq(SysDictData::getDictType, dictType)
+                .orderByAsc(SysDictData::getDictSort));
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysDictTypeMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysDictTypeMapper.java
new file mode 100644
index 0000000..9a9bdd5
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysDictTypeMapper.java
@@ -0,0 +1,14 @@
+package org.dromara.system.mapper;
+
+import org.dromara.system.domain.SysDictType;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.system.domain.vo.SysDictTypeVo;
+
+/**
+ * 瀛楀吀琛� 鏁版嵁灞�
+ *
+ * @author Lion Li
+ */
+public interface SysDictTypeMapper extends BaseMapperPlus<SysDictType, SysDictTypeVo> {
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysLogininforMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysLogininforMapper.java
new file mode 100644
index 0000000..85edd1d
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysLogininforMapper.java
@@ -0,0 +1,14 @@
+package org.dromara.system.mapper;
+
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.system.domain.SysLogininfor;
+import org.dromara.system.domain.vo.SysLogininforVo;
+
+/**
+ * 绯荤粺璁块棶鏃ュ織鎯呭喌淇℃伅 鏁版嵁灞�
+ *
+ * @author Lion Li
+ */
+public interface SysLogininforMapper extends BaseMapperPlus<SysLogininfor, SysLogininforVo> {
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysMenuMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysMenuMapper.java
new file mode 100644
index 0000000..b2be0e9
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysMenuMapper.java
@@ -0,0 +1,83 @@
+package org.dromara.system.mapper;
+
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import org.dromara.common.core.constant.UserConstants;
+import org.dromara.system.domain.SysMenu;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.system.domain.vo.SysMenuVo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 鑿滃崟琛� 鏁版嵁灞�
+ *
+ * @author Lion Li
+ */
+public interface SysMenuMapper extends BaseMapperPlus<SysMenu, SysMenuVo> {
+
+    /**
+     * 鏍规嵁鐢ㄦ埛鎵�鏈夋潈闄�
+     *
+     * @return 鏉冮檺鍒楄〃
+     */
+    List<String> selectMenuPerms();
+
+    /**
+     * 鏍规嵁鐢ㄦ埛鏌ヨ绯荤粺鑿滃崟鍒楄〃
+     *
+     * @param queryWrapper 鏌ヨ鏉′欢
+     * @return 鑿滃崟鍒楄〃
+     */
+    List<SysMenu> selectMenuListByUserId(@Param(Constants.WRAPPER) Wrapper<SysMenu> queryWrapper);
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鏌ヨ鏉冮檺
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 鏉冮檺鍒楄〃
+     */
+    List<String> selectMenuPermsByUserId(Long userId);
+
+    /**
+     * 鏍规嵁瑙掕壊ID鏌ヨ鏉冮檺
+     *
+     * @param roleId 瑙掕壊ID
+     * @return 鏉冮檺鍒楄〃
+     */
+    List<String> selectMenuPermsByRoleId(Long roleId);
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鏌ヨ鑿滃崟
+     *
+     * @return 鑿滃崟鍒楄〃
+     */
+    default List<SysMenu> selectMenuTreeAll() {
+        LambdaQueryWrapper<SysMenu> lqw = new LambdaQueryWrapper<SysMenu>()
+            .in(SysMenu::getMenuType, UserConstants.TYPE_DIR, UserConstants.TYPE_MENU)
+            .eq(SysMenu::getStatus, UserConstants.MENU_NORMAL)
+            .orderByAsc(SysMenu::getParentId)
+            .orderByAsc(SysMenu::getOrderNum);
+        return this.selectList(lqw);
+    }
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鏌ヨ鑿滃崟
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 鑿滃崟鍒楄〃
+     */
+    List<SysMenu> selectMenuTreeByUserId(Long userId);
+
+    /**
+     * 鏍规嵁瑙掕壊ID鏌ヨ鑿滃崟鏍戜俊鎭�
+     *
+     * @param roleId            瑙掕壊ID
+     * @param menuCheckStrictly 鑿滃崟鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�
+     * @return 閫変腑鑿滃崟鍒楄〃
+     */
+    List<Long> selectMenuListByRoleId(@Param("roleId") Long roleId, @Param("menuCheckStrictly") boolean menuCheckStrictly);
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysNoticeMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysNoticeMapper.java
new file mode 100644
index 0000000..1e27b77
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysNoticeMapper.java
@@ -0,0 +1,14 @@
+package org.dromara.system.mapper;
+
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.system.domain.SysNotice;
+import org.dromara.system.domain.vo.SysNoticeVo;
+
+/**
+ * 閫氱煡鍏憡琛� 鏁版嵁灞�
+ *
+ * @author Lion Li
+ */
+public interface SysNoticeMapper extends BaseMapperPlus<SysNotice, SysNoticeVo> {
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysOperLogMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysOperLogMapper.java
new file mode 100644
index 0000000..5d20404
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysOperLogMapper.java
@@ -0,0 +1,14 @@
+package org.dromara.system.mapper;
+
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.system.domain.SysOperLog;
+import org.dromara.system.domain.vo.SysOperLogVo;
+
+/**
+ * 鎿嶄綔鏃ュ織 鏁版嵁灞�
+ *
+ * @author Lion Li
+ */
+public interface SysOperLogMapper extends BaseMapperPlus<SysOperLog, SysOperLogVo> {
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysOssConfigMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysOssConfigMapper.java
new file mode 100644
index 0000000..f93d34d
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysOssConfigMapper.java
@@ -0,0 +1,16 @@
+package org.dromara.system.mapper;
+
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.system.domain.SysOssConfig;
+import org.dromara.system.domain.vo.SysOssConfigVo;
+
+/**
+ * 瀵硅薄瀛樺偍閰嶇疆Mapper鎺ュ彛
+ *
+ * @author Lion Li
+ * @author 瀛よ垷鐑熼洦
+ * @date 2021-08-13
+ */
+public interface SysOssConfigMapper extends BaseMapperPlus<SysOssConfig, SysOssConfigVo> {
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysOssMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysOssMapper.java
new file mode 100644
index 0000000..3da621d
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysOssMapper.java
@@ -0,0 +1,13 @@
+package org.dromara.system.mapper;
+
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.system.domain.SysOss;
+import org.dromara.system.domain.vo.SysOssVo;
+
+/**
+ * 鏂囦欢涓婁紶 鏁版嵁灞�
+ *
+ * @author Lion Li
+ */
+public interface SysOssMapper extends BaseMapperPlus<SysOss, SysOssVo> {
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysPostMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysPostMapper.java
new file mode 100644
index 0000000..48e6a12
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysPostMapper.java
@@ -0,0 +1,32 @@
+package org.dromara.system.mapper;
+
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.system.domain.SysPost;
+import org.dromara.system.domain.vo.SysPostVo;
+
+import java.util.List;
+
+/**
+ * 宀椾綅淇℃伅 鏁版嵁灞�
+ *
+ * @author Lion Li
+ */
+public interface SysPostMapper extends BaseMapperPlus<SysPost, SysPostVo> {
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鑾峰彇宀椾綅閫夋嫨妗嗗垪琛�
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 閫変腑宀椾綅ID鍒楄〃
+     */
+    List<Long> selectPostListByUserId(Long userId);
+
+    /**
+     * 鏌ヨ鐢ㄦ埛鎵�灞炲矖浣嶇粍
+     *
+     * @param userName 鐢ㄦ埛鍚�
+     * @return 缁撴灉
+     */
+    List<SysPostVo> selectPostsByUserName(String userName);
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysRoleDeptMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysRoleDeptMapper.java
new file mode 100644
index 0000000..3de0bb6
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysRoleDeptMapper.java
@@ -0,0 +1,13 @@
+package org.dromara.system.mapper;
+
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.system.domain.SysRoleDept;
+
+/**
+ * 瑙掕壊涓庨儴闂ㄥ叧鑱旇〃 鏁版嵁灞�
+ *
+ * @author Lion Li
+ */
+public interface SysRoleDeptMapper extends BaseMapperPlus<SysRoleDept, SysRoleDept> {
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysRoleMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysRoleMapper.java
new file mode 100644
index 0000000..a0a29b1
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysRoleMapper.java
@@ -0,0 +1,68 @@
+package org.dromara.system.mapper;
+
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.dromara.common.mybatis.annotation.DataColumn;
+import org.dromara.common.mybatis.annotation.DataPermission;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.system.domain.SysRole;
+import org.dromara.system.domain.vo.SysRoleVo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 瑙掕壊琛� 鏁版嵁灞�
+ *
+ * @author Lion Li
+ */
+public interface SysRoleMapper extends BaseMapperPlus<SysRole, SysRoleVo> {
+
+    @DataPermission({
+        @DataColumn(key = "deptName", value = "d.dept_id")
+    })
+    Page<SysRoleVo> selectPageRoleList(@Param("page") Page<SysRole> page, @Param(Constants.WRAPPER) Wrapper<SysRole> queryWrapper);
+
+    /**
+     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瑙掕壊鏁版嵁
+     *
+     * @param queryWrapper 鏌ヨ鏉′欢
+     * @return 瑙掕壊鏁版嵁闆嗗悎淇℃伅
+     */
+    @DataPermission({
+        @DataColumn(key = "deptName", value = "d.dept_id")
+    })
+    List<SysRoleVo> selectRoleList(@Param(Constants.WRAPPER) Wrapper<SysRole> queryWrapper);
+
+    @DataPermission({
+        @DataColumn(key = "deptName", value = "d.dept_id")
+    })
+    SysRoleVo selectRoleById(Long roleId);
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鏌ヨ瑙掕壊
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 瑙掕壊鍒楄〃
+     */
+    List<SysRoleVo> selectRolePermissionByUserId(Long userId);
+
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鑾峰彇瑙掕壊閫夋嫨妗嗗垪琛�
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 閫変腑瑙掕壊ID鍒楄〃
+     */
+    List<Long> selectRoleListByUserId(Long userId);
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鏌ヨ瑙掕壊
+     *
+     * @param userName 鐢ㄦ埛鍚�
+     * @return 瑙掕壊鍒楄〃
+     */
+    List<SysRoleVo> selectRolesByUserName(String userName);
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysRoleMenuMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysRoleMenuMapper.java
new file mode 100644
index 0000000..0a657b4
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysRoleMenuMapper.java
@@ -0,0 +1,13 @@
+package org.dromara.system.mapper;
+
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.system.domain.SysRoleMenu;
+
+/**
+ * 瑙掕壊涓庤彍鍗曞叧鑱旇〃 鏁版嵁灞�
+ *
+ * @author Lion Li
+ */
+public interface SysRoleMenuMapper extends BaseMapperPlus<SysRoleMenu, SysRoleMenu> {
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysTenantMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysTenantMapper.java
new file mode 100644
index 0000000..7e1167a
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysTenantMapper.java
@@ -0,0 +1,14 @@
+package org.dromara.system.mapper;
+
+import org.dromara.system.domain.SysTenant;
+import org.dromara.system.domain.vo.SysTenantVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 绉熸埛Mapper鎺ュ彛
+ *
+ * @author Michelle.Chung
+ */
+public interface SysTenantMapper extends BaseMapperPlus<SysTenant, SysTenantVo> {
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysTenantPackageMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysTenantPackageMapper.java
new file mode 100644
index 0000000..10ca170
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysTenantPackageMapper.java
@@ -0,0 +1,14 @@
+package org.dromara.system.mapper;
+
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.system.domain.SysTenantPackage;
+import org.dromara.system.domain.vo.SysTenantPackageVo;
+
+/**
+ * 绉熸埛濂楅Mapper鎺ュ彛
+ *
+ * @author Michelle.Chung
+ */
+public interface SysTenantPackageMapper extends BaseMapperPlus<SysTenantPackage, SysTenantPackageVo> {
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java
new file mode 100644
index 0000000..81bd1ff
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java
@@ -0,0 +1,145 @@
+package org.dromara.system.mapper;
+
+import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.dromara.common.mybatis.annotation.DataColumn;
+import org.dromara.common.mybatis.annotation.DataPermission;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.system.domain.SysUser;
+import org.dromara.system.domain.vo.SysUserVo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 鐢ㄦ埛琛� 鏁版嵁灞�
+ *
+ * @author Lion Li
+ */
+public interface SysUserMapper extends BaseMapperPlus<SysUser, SysUserVo> {
+
+    @DataPermission({
+        @DataColumn(key = "deptName", value = "d.dept_id"),
+        @DataColumn(key = "userName", value = "u.user_id")
+    })
+    Page<SysUserVo> selectPageUserList(@Param("page") Page<SysUser> page, @Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);
+
+    /**
+     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ鐢ㄦ埛鍒楄〃
+     *
+     * @param queryWrapper 鏌ヨ鏉′欢
+     * @return 鐢ㄦ埛淇℃伅闆嗗悎淇℃伅
+     */
+    @DataPermission({
+        @DataColumn(key = "deptName", value = "d.dept_id"),
+        @DataColumn(key = "userName", value = "u.user_id")
+    })
+    List<SysUserVo> selectUserList(@Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);
+
+    /**
+     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ宸查厤鐢ㄦ埛瑙掕壊鍒楄〃
+     *
+     * @param queryWrapper 鏌ヨ鏉′欢
+     * @return 鐢ㄦ埛淇℃伅闆嗗悎淇℃伅
+     */
+    @DataPermission({
+        @DataColumn(key = "deptName", value = "d.dept_id"),
+        @DataColumn(key = "userName", value = "u.user_id")
+    })
+    Page<SysUserVo> selectAllocatedList(@Param("page") Page<SysUser> page, @Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);
+
+    /**
+     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ鏈垎閰嶇敤鎴疯鑹插垪琛�
+     *
+     * @param queryWrapper 鏌ヨ鏉′欢
+     * @return 鐢ㄦ埛淇℃伅闆嗗悎淇℃伅
+     */
+    @DataPermission({
+        @DataColumn(key = "deptName", value = "d.dept_id"),
+        @DataColumn(key = "userName", value = "u.user_id")
+    })
+    Page<SysUserVo> selectUnallocatedList(@Param("page") Page<SysUser> page, @Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);
+
+    /**
+     * 閫氳繃鐢ㄦ埛鍚嶆煡璇㈢敤鎴�
+     *
+     * @param userName 鐢ㄦ埛鍚�
+     * @return 鐢ㄦ埛瀵硅薄淇℃伅
+     */
+    SysUserVo selectUserByUserName(String userName);
+
+    /**
+     * 閫氳繃鎵嬫満鍙锋煡璇㈢敤鎴�
+     *
+     * @param phonenumber 鎵嬫満鍙�
+     * @return 鐢ㄦ埛瀵硅薄淇℃伅
+     */
+    SysUserVo selectUserByPhonenumber(String phonenumber);
+
+    /**
+     * 閫氳繃閭鏌ヨ鐢ㄦ埛
+     *
+     * @param email 閭
+     * @return 鐢ㄦ埛瀵硅薄淇℃伅
+     */
+    SysUserVo selectUserByEmail(String email);
+
+    /**
+     * 閫氳繃鐢ㄦ埛鍚嶆煡璇㈢敤鎴�(涓嶈蛋绉熸埛鎻掍欢)
+     *
+     * @param userName 鐢ㄦ埛鍚�
+     * @param tenantId 绉熸埛id
+     * @return 鐢ㄦ埛瀵硅薄淇℃伅
+     */
+    @InterceptorIgnore(tenantLine = "true")
+    SysUserVo selectTenantUserByUserName(String userName, String tenantId);
+
+    /**
+     * 閫氳繃鎵嬫満鍙锋煡璇㈢敤鎴�(涓嶈蛋绉熸埛鎻掍欢)
+     *
+     * @param phonenumber 鎵嬫満鍙�
+     * @param tenantId    绉熸埛id
+     * @return 鐢ㄦ埛瀵硅薄淇℃伅
+     */
+    @InterceptorIgnore(tenantLine = "true")
+    SysUserVo selectTenantUserByPhonenumber(String phonenumber, String tenantId);
+
+    /**
+     * 閫氳繃閭鏌ヨ鐢ㄦ埛(涓嶈蛋绉熸埛鎻掍欢)
+     *
+     * @param email    閭
+     * @param tenantId 绉熸埛id
+     * @return 鐢ㄦ埛瀵硅薄淇℃伅
+     */
+    @InterceptorIgnore(tenantLine = "true")
+    SysUserVo selectTenantUserByEmail(String email, String tenantId);
+
+    /**
+     * 閫氳繃鐢ㄦ埛ID鏌ヨ鐢ㄦ埛
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 鐢ㄦ埛瀵硅薄淇℃伅
+     */
+    @DataPermission({
+        @DataColumn(key = "deptName", value = "d.dept_id"),
+        @DataColumn(key = "userName", value = "u.user_id")
+    })
+    SysUserVo selectUserById(Long userId);
+
+    @Override
+    @DataPermission({
+        @DataColumn(key = "deptName", value = "dept_id"),
+        @DataColumn(key = "userName", value = "user_id")
+    })
+    int update(@Param(Constants.ENTITY) SysUser user, @Param(Constants.WRAPPER) Wrapper<SysUser> updateWrapper);
+
+    @Override
+    @DataPermission({
+        @DataColumn(key = "deptName", value = "dept_id"),
+        @DataColumn(key = "userName", value = "user_id")
+    })
+    int updateById(@Param(Constants.ENTITY) SysUser user);
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserPostMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserPostMapper.java
new file mode 100644
index 0000000..07c1371
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserPostMapper.java
@@ -0,0 +1,13 @@
+package org.dromara.system.mapper;
+
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.system.domain.SysUserPost;
+
+/**
+ * 鐢ㄦ埛涓庡矖浣嶅叧鑱旇〃 鏁版嵁灞�
+ *
+ * @author Lion Li
+ */
+public interface SysUserPostMapper extends BaseMapperPlus<SysUserPost, SysUserPost> {
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserRoleMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserRoleMapper.java
new file mode 100644
index 0000000..e2f706c
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserRoleMapper.java
@@ -0,0 +1,17 @@
+package org.dromara.system.mapper;
+
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.system.domain.SysUserRole;
+
+import java.util.List;
+
+/**
+ * 鐢ㄦ埛涓庤鑹插叧鑱旇〃 鏁版嵁灞�
+ *
+ * @author Lion Li
+ */
+public interface SysUserRoleMapper extends BaseMapperPlus<SysUserRole, SysUserRole> {
+
+    List<Long> selectUserIdsByRoleId(Long roleId);
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/runner/SystemApplicationRunner.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/runner/SystemApplicationRunner.java
new file mode 100644
index 0000000..27dad7d
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/runner/SystemApplicationRunner.java
@@ -0,0 +1,28 @@
+package org.dromara.system.runner;
+
+import org.dromara.system.service.ISysOssConfigService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.stereotype.Component;
+
+/**
+ * 鍒濆鍖� system 妯″潡瀵瑰簲涓氬姟鏁版嵁
+ *
+ * @author Lion Li
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Component
+public class SystemApplicationRunner implements ApplicationRunner {
+
+    private final ISysOssConfigService ossConfigService;
+
+    @Override
+    public void run(ApplicationArguments args) throws Exception {
+        ossConfigService.init();
+        log.info("鍒濆鍖朞SS閰嶇疆鎴愬姛");
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysConfigService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysConfigService.java
new file mode 100644
index 0000000..f7efda7
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysConfigService.java
@@ -0,0 +1,87 @@
+package org.dromara.system.service;
+
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.system.domain.bo.SysConfigBo;
+import org.dromara.system.domain.vo.SysConfigVo;
+
+import java.util.List;
+
+/**
+ * 鍙傛暟閰嶇疆 鏈嶅姟灞�
+ *
+ * @author Lion Li
+ */
+public interface ISysConfigService {
+
+
+    TableDataInfo<SysConfigVo> selectPageConfigList(SysConfigBo config, PageQuery pageQuery);
+
+    /**
+     * 鏌ヨ鍙傛暟閰嶇疆淇℃伅
+     *
+     * @param configId 鍙傛暟閰嶇疆ID
+     * @return 鍙傛暟閰嶇疆淇℃伅
+     */
+    SysConfigVo selectConfigById(Long configId);
+
+    /**
+     * 鏍规嵁閿悕鏌ヨ鍙傛暟閰嶇疆淇℃伅
+     *
+     * @param configKey 鍙傛暟閿悕
+     * @return 鍙傛暟閿��
+     */
+    String selectConfigByKey(String configKey);
+
+    /**
+     * 鑾峰彇娉ㄥ唽寮�鍏�
+     * @param tenantId 绉熸埛id
+     * @return true寮�鍚紝false鍏抽棴
+     */
+    boolean selectRegisterEnabled(String tenantId);
+
+    /**
+     * 鏌ヨ鍙傛暟閰嶇疆鍒楄〃
+     *
+     * @param config 鍙傛暟閰嶇疆淇℃伅
+     * @return 鍙傛暟閰嶇疆闆嗗悎
+     */
+    List<SysConfigVo> selectConfigList(SysConfigBo config);
+
+    /**
+     * 鏂板鍙傛暟閰嶇疆
+     *
+     * @param bo 鍙傛暟閰嶇疆淇℃伅
+     * @return 缁撴灉
+     */
+    String insertConfig(SysConfigBo bo);
+
+    /**
+     * 淇敼鍙傛暟閰嶇疆
+     *
+     * @param bo 鍙傛暟閰嶇疆淇℃伅
+     * @return 缁撴灉
+     */
+    String updateConfig(SysConfigBo bo);
+
+    /**
+     * 鎵归噺鍒犻櫎鍙傛暟淇℃伅
+     *
+     * @param configIds 闇�瑕佸垹闄ょ殑鍙傛暟ID
+     */
+    void deleteConfigByIds(Long[] configIds);
+
+    /**
+     * 閲嶇疆鍙傛暟缂撳瓨鏁版嵁
+     */
+    void resetConfigCache();
+
+    /**
+     * 鏍¢獙鍙傛暟閿悕鏄惁鍞竴
+     *
+     * @param config 鍙傛暟淇℃伅
+     * @return 缁撴灉
+     */
+    boolean checkConfigKeyUnique(SysConfigBo config);
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDataScopeService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDataScopeService.java
new file mode 100644
index 0000000..3f252f7
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDataScopeService.java
@@ -0,0 +1,26 @@
+package org.dromara.system.service;
+
+/**
+ * 閫氱敤 鏁版嵁鏉冮檺 鏈嶅姟
+ *
+ * @author Lion Li
+ */
+public interface ISysDataScopeService {
+
+    /**
+     * 鑾峰彇瑙掕壊鑷畾涔夋潈闄�
+     *
+     * @param roleId 瑙掕壊id
+     * @return 閮ㄩ棬id缁�
+     */
+    String getRoleCustom(Long roleId);
+
+    /**
+     * 鑾峰彇閮ㄩ棬鍙婁互涓嬫潈闄�
+     *
+     * @param deptId 閮ㄩ棬id
+     * @return 閮ㄩ棬id缁�
+     */
+    String getDeptAndChild(Long deptId);
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDeptService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDeptService.java
new file mode 100644
index 0000000..1d32779
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDeptService.java
@@ -0,0 +1,118 @@
+package org.dromara.system.service;
+
+import cn.hutool.core.lang.tree.Tree;
+import org.dromara.system.domain.SysDept;
+import org.dromara.system.domain.bo.SysDeptBo;
+import org.dromara.system.domain.vo.SysDeptVo;
+
+import java.util.List;
+
+/**
+ * 閮ㄩ棬绠$悊 鏈嶅姟灞�
+ *
+ * @author Lion Li
+ */
+public interface ISysDeptService {
+    /**
+     * 鏌ヨ閮ㄩ棬绠$悊鏁版嵁
+     *
+     * @param dept 閮ㄩ棬淇℃伅
+     * @return 閮ㄩ棬淇℃伅闆嗗悎
+     */
+    List<SysDeptVo> selectDeptList(SysDeptBo dept);
+
+    /**
+     * 鏌ヨ閮ㄩ棬鏍戠粨鏋勪俊鎭�
+     *
+     * @param dept 閮ㄩ棬淇℃伅
+     * @return 閮ㄩ棬鏍戜俊鎭泦鍚�
+     */
+    List<Tree<Long>> selectDeptTreeList(SysDeptBo dept);
+
+    /**
+     * 鏋勫缓鍓嶇鎵�闇�瑕佷笅鎷夋爲缁撴瀯
+     *
+     * @param depts 閮ㄩ棬鍒楄〃
+     * @return 涓嬫媺鏍戠粨鏋勫垪琛�
+     */
+    List<Tree<Long>> buildDeptTreeSelect(List<SysDept> depts);
+
+    /**
+     * 鏍规嵁瑙掕壊ID鏌ヨ閮ㄩ棬鏍戜俊鎭�
+     *
+     * @param roleId 瑙掕壊ID
+     * @return 閫変腑閮ㄩ棬鍒楄〃
+     */
+    List<Long> selectDeptListByRoleId(Long roleId);
+
+    /**
+     * 鏍规嵁閮ㄩ棬ID鏌ヨ淇℃伅
+     *
+     * @param deptId 閮ㄩ棬ID
+     * @return 閮ㄩ棬淇℃伅
+     */
+    SysDeptVo selectDeptById(Long deptId);
+
+    /**
+     * 鏍规嵁ID鏌ヨ鎵�鏈夊瓙閮ㄩ棬鏁帮紙姝e父鐘舵�侊級
+     *
+     * @param deptId 閮ㄩ棬ID
+     * @return 瀛愰儴闂ㄦ暟
+     */
+    long selectNormalChildrenDeptById(Long deptId);
+
+    /**
+     * 鏄惁瀛樺湪閮ㄩ棬瀛愯妭鐐�
+     *
+     * @param deptId 閮ㄩ棬ID
+     * @return 缁撴灉
+     */
+    boolean hasChildByDeptId(Long deptId);
+
+    /**
+     * 鏌ヨ閮ㄩ棬鏄惁瀛樺湪鐢ㄦ埛
+     *
+     * @param deptId 閮ㄩ棬ID
+     * @return 缁撴灉 true 瀛樺湪 false 涓嶅瓨鍦�
+     */
+    boolean checkDeptExistUser(Long deptId);
+
+    /**
+     * 鏍¢獙閮ㄩ棬鍚嶇О鏄惁鍞竴
+     *
+     * @param dept 閮ㄩ棬淇℃伅
+     * @return 缁撴灉
+     */
+    boolean checkDeptNameUnique(SysDeptBo dept);
+
+    /**
+     * 鏍¢獙閮ㄩ棬鏄惁鏈夋暟鎹潈闄�
+     *
+     * @param deptId 閮ㄩ棬id
+     */
+    void checkDeptDataScope(Long deptId);
+
+    /**
+     * 鏂板淇濆瓨閮ㄩ棬淇℃伅
+     *
+     * @param bo 閮ㄩ棬淇℃伅
+     * @return 缁撴灉
+     */
+    int insertDept(SysDeptBo bo);
+
+    /**
+     * 淇敼淇濆瓨閮ㄩ棬淇℃伅
+     *
+     * @param bo 閮ㄩ棬淇℃伅
+     * @return 缁撴灉
+     */
+    int updateDept(SysDeptBo bo);
+
+    /**
+     * 鍒犻櫎閮ㄩ棬绠$悊淇℃伅
+     *
+     * @param deptId 閮ㄩ棬ID
+     * @return 缁撴灉
+     */
+    int deleteDeptById(Long deptId);
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDictDataService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDictDataService.java
new file mode 100644
index 0000000..30442ce
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDictDataService.java
@@ -0,0 +1,67 @@
+package org.dromara.system.service;
+
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.system.domain.bo.SysDictDataBo;
+import org.dromara.system.domain.vo.SysDictDataVo;
+
+import java.util.List;
+
+/**
+ * 瀛楀吀 涓氬姟灞�
+ *
+ * @author Lion Li
+ */
+public interface ISysDictDataService {
+
+
+    TableDataInfo<SysDictDataVo> selectPageDictDataList(SysDictDataBo dictData, PageQuery pageQuery);
+
+    /**
+     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瀛楀吀鏁版嵁
+     *
+     * @param dictData 瀛楀吀鏁版嵁淇℃伅
+     * @return 瀛楀吀鏁版嵁闆嗗悎淇℃伅
+     */
+    List<SysDictDataVo> selectDictDataList(SysDictDataBo dictData);
+
+    /**
+     * 鏍规嵁瀛楀吀绫诲瀷鍜屽瓧鍏搁敭鍊兼煡璇㈠瓧鍏告暟鎹俊鎭�
+     *
+     * @param dictType  瀛楀吀绫诲瀷
+     * @param dictValue 瀛楀吀閿��
+     * @return 瀛楀吀鏍囩
+     */
+    String selectDictLabel(String dictType, String dictValue);
+
+    /**
+     * 鏍规嵁瀛楀吀鏁版嵁ID鏌ヨ淇℃伅
+     *
+     * @param dictCode 瀛楀吀鏁版嵁ID
+     * @return 瀛楀吀鏁版嵁
+     */
+    SysDictDataVo selectDictDataById(Long dictCode);
+
+    /**
+     * 鎵归噺鍒犻櫎瀛楀吀鏁版嵁淇℃伅
+     *
+     * @param dictCodes 闇�瑕佸垹闄ょ殑瀛楀吀鏁版嵁ID
+     */
+    void deleteDictDataByIds(Long[] dictCodes);
+
+    /**
+     * 鏂板淇濆瓨瀛楀吀鏁版嵁淇℃伅
+     *
+     * @param bo 瀛楀吀鏁版嵁淇℃伅
+     * @return 缁撴灉
+     */
+    List<SysDictDataVo> insertDictData(SysDictDataBo bo);
+
+    /**
+     * 淇敼淇濆瓨瀛楀吀鏁版嵁淇℃伅
+     *
+     * @param bo 瀛楀吀鏁版嵁淇℃伅
+     * @return 缁撴灉
+     */
+    List<SysDictDataVo> updateDictData(SysDictDataBo bo);
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDictTypeService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDictTypeService.java
new file mode 100644
index 0000000..52cdd2b
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDictTypeService.java
@@ -0,0 +1,95 @@
+package org.dromara.system.service;
+
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.system.domain.bo.SysDictTypeBo;
+import org.dromara.system.domain.vo.SysDictDataVo;
+import org.dromara.system.domain.vo.SysDictTypeVo;
+
+import java.util.List;
+
+/**
+ * 瀛楀吀 涓氬姟灞�
+ *
+ * @author Lion Li
+ */
+public interface ISysDictTypeService {
+
+
+    TableDataInfo<SysDictTypeVo> selectPageDictTypeList(SysDictTypeBo dictType, PageQuery pageQuery);
+
+    /**
+     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瀛楀吀绫诲瀷
+     *
+     * @param dictType 瀛楀吀绫诲瀷淇℃伅
+     * @return 瀛楀吀绫诲瀷闆嗗悎淇℃伅
+     */
+    List<SysDictTypeVo> selectDictTypeList(SysDictTypeBo dictType);
+
+    /**
+     * 鏍规嵁鎵�鏈夊瓧鍏哥被鍨�
+     *
+     * @return 瀛楀吀绫诲瀷闆嗗悎淇℃伅
+     */
+    List<SysDictTypeVo> selectDictTypeAll();
+
+    /**
+     * 鏍规嵁瀛楀吀绫诲瀷鏌ヨ瀛楀吀鏁版嵁
+     *
+     * @param dictType 瀛楀吀绫诲瀷
+     * @return 瀛楀吀鏁版嵁闆嗗悎淇℃伅
+     */
+    List<SysDictDataVo> selectDictDataByType(String dictType);
+
+    /**
+     * 鏍规嵁瀛楀吀绫诲瀷ID鏌ヨ淇℃伅
+     *
+     * @param dictId 瀛楀吀绫诲瀷ID
+     * @return 瀛楀吀绫诲瀷
+     */
+    SysDictTypeVo selectDictTypeById(Long dictId);
+
+    /**
+     * 鏍规嵁瀛楀吀绫诲瀷鏌ヨ淇℃伅
+     *
+     * @param dictType 瀛楀吀绫诲瀷
+     * @return 瀛楀吀绫诲瀷
+     */
+    SysDictTypeVo selectDictTypeByType(String dictType);
+
+    /**
+     * 鎵归噺鍒犻櫎瀛楀吀淇℃伅
+     *
+     * @param dictIds 闇�瑕佸垹闄ょ殑瀛楀吀ID
+     */
+    void deleteDictTypeByIds(Long[] dictIds);
+
+    /**
+     * 閲嶇疆瀛楀吀缂撳瓨鏁版嵁
+     */
+    void resetDictCache();
+
+    /**
+     * 鏂板淇濆瓨瀛楀吀绫诲瀷淇℃伅
+     *
+     * @param bo 瀛楀吀绫诲瀷淇℃伅
+     * @return 缁撴灉
+     */
+    List<SysDictTypeVo> insertDictType(SysDictTypeBo bo);
+
+    /**
+     * 淇敼淇濆瓨瀛楀吀绫诲瀷淇℃伅
+     *
+     * @param bo 瀛楀吀绫诲瀷淇℃伅
+     * @return 缁撴灉
+     */
+    List<SysDictDataVo> updateDictType(SysDictTypeBo bo);
+
+    /**
+     * 鏍¢獙瀛楀吀绫诲瀷绉版槸鍚﹀敮涓�
+     *
+     * @param dictType 瀛楀吀绫诲瀷
+     * @return 缁撴灉
+     */
+    boolean checkDictTypeUnique(SysDictTypeBo dictType);
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysLogininforService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysLogininforService.java
new file mode 100644
index 0000000..6b3b7a6
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysLogininforService.java
@@ -0,0 +1,47 @@
+package org.dromara.system.service;
+
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.system.domain.bo.SysLogininforBo;
+import org.dromara.system.domain.vo.SysLogininforVo;
+
+import java.util.List;
+
+/**
+ * 绯荤粺璁块棶鏃ュ織鎯呭喌淇℃伅 鏈嶅姟灞�
+ *
+ * @author Lion Li
+ */
+public interface ISysLogininforService {
+
+
+    TableDataInfo<SysLogininforVo> selectPageLogininforList(SysLogininforBo logininfor, PageQuery pageQuery);
+
+    /**
+     * 鏂板绯荤粺鐧诲綍鏃ュ織
+     *
+     * @param bo 璁块棶鏃ュ織瀵硅薄
+     */
+    void insertLogininfor(SysLogininforBo bo);
+
+    /**
+     * 鏌ヨ绯荤粺鐧诲綍鏃ュ織闆嗗悎
+     *
+     * @param logininfor 璁块棶鏃ュ織瀵硅薄
+     * @return 鐧诲綍璁板綍闆嗗悎
+     */
+    List<SysLogininforVo> selectLogininforList(SysLogininforBo logininfor);
+
+    /**
+     * 鎵归噺鍒犻櫎绯荤粺鐧诲綍鏃ュ織
+     *
+     * @param infoIds 闇�瑕佸垹闄ょ殑鐧诲綍鏃ュ織ID
+     * @return 缁撴灉
+     */
+    int deleteLogininforByIds(Long[] infoIds);
+
+    /**
+     * 娓呯┖绯荤粺鐧诲綍鏃ュ織
+     */
+    void cleanLogininfor();
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysMenuService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysMenuService.java
new file mode 100644
index 0000000..72d705e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysMenuService.java
@@ -0,0 +1,147 @@
+package org.dromara.system.service;
+
+import cn.hutool.core.lang.tree.Tree;
+import org.dromara.system.domain.SysMenu;
+import org.dromara.system.domain.bo.SysMenuBo;
+import org.dromara.system.domain.vo.RouterVo;
+import org.dromara.system.domain.vo.SysMenuVo;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 鑿滃崟 涓氬姟灞�
+ *
+ * @author Lion Li
+ */
+public interface ISysMenuService {
+
+    /**
+     * 鏍规嵁鐢ㄦ埛鏌ヨ绯荤粺鑿滃崟鍒楄〃
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 鑿滃崟鍒楄〃
+     */
+    List<SysMenuVo> selectMenuList(Long userId);
+
+    /**
+     * 鏍规嵁鐢ㄦ埛鏌ヨ绯荤粺鑿滃崟鍒楄〃
+     *
+     * @param menu   鑿滃崟淇℃伅
+     * @param userId 鐢ㄦ埛ID
+     * @return 鑿滃崟鍒楄〃
+     */
+    List<SysMenuVo> selectMenuList(SysMenuBo menu, Long userId);
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鏌ヨ鏉冮檺
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 鏉冮檺鍒楄〃
+     */
+    Set<String> selectMenuPermsByUserId(Long userId);
+
+    /**
+     * 鏍规嵁瑙掕壊ID鏌ヨ鏉冮檺
+     *
+     * @param roleId 瑙掕壊ID
+     * @return 鏉冮檺鍒楄〃
+     */
+    Set<String> selectMenuPermsByRoleId(Long roleId);
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鏌ヨ鑿滃崟鏍戜俊鎭�
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 鑿滃崟鍒楄〃
+     */
+    List<SysMenu> selectMenuTreeByUserId(Long userId);
+
+    /**
+     * 鏍规嵁瑙掕壊ID鏌ヨ鑿滃崟鏍戜俊鎭�
+     *
+     * @param roleId 瑙掕壊ID
+     * @return 閫変腑鑿滃崟鍒楄〃
+     */
+    List<Long> selectMenuListByRoleId(Long roleId);
+
+    /**
+     * 鏍规嵁绉熸埛濂楅ID鏌ヨ鑿滃崟鏍戜俊鎭�
+     *
+     * @param packageId 绉熸埛濂楅ID
+     * @return 閫変腑鑿滃崟鍒楄〃
+     */
+    List<Long> selectMenuListByPackageId(Long packageId);
+
+    /**
+     * 鏋勫缓鍓嶇璺敱鎵�闇�瑕佺殑鑿滃崟
+     *
+     * @param menus 鑿滃崟鍒楄〃
+     * @return 璺敱鍒楄〃
+     */
+    List<RouterVo> buildMenus(List<SysMenu> menus);
+
+    /**
+     * 鏋勫缓鍓嶇鎵�闇�瑕佷笅鎷夋爲缁撴瀯
+     *
+     * @param menus 鑿滃崟鍒楄〃
+     * @return 涓嬫媺鏍戠粨鏋勫垪琛�
+     */
+    List<Tree<Long>> buildMenuTreeSelect(List<SysMenuVo> menus);
+
+    /**
+     * 鏍规嵁鑿滃崟ID鏌ヨ淇℃伅
+     *
+     * @param menuId 鑿滃崟ID
+     * @return 鑿滃崟淇℃伅
+     */
+    SysMenuVo selectMenuById(Long menuId);
+
+    /**
+     * 鏄惁瀛樺湪鑿滃崟瀛愯妭鐐�
+     *
+     * @param menuId 鑿滃崟ID
+     * @return 缁撴灉 true 瀛樺湪 false 涓嶅瓨鍦�
+     */
+    boolean hasChildByMenuId(Long menuId);
+
+    /**
+     * 鏌ヨ鑿滃崟鏄惁瀛樺湪瑙掕壊
+     *
+     * @param menuId 鑿滃崟ID
+     * @return 缁撴灉 true 瀛樺湪 false 涓嶅瓨鍦�
+     */
+    boolean checkMenuExistRole(Long menuId);
+
+    /**
+     * 鏂板淇濆瓨鑿滃崟淇℃伅
+     *
+     * @param bo 鑿滃崟淇℃伅
+     * @return 缁撴灉
+     */
+    int insertMenu(SysMenuBo bo);
+
+    /**
+     * 淇敼淇濆瓨鑿滃崟淇℃伅
+     *
+     * @param bo 鑿滃崟淇℃伅
+     * @return 缁撴灉
+     */
+    int updateMenu(SysMenuBo bo);
+
+    /**
+     * 鍒犻櫎鑿滃崟绠$悊淇℃伅
+     *
+     * @param menuId 鑿滃崟ID
+     * @return 缁撴灉
+     */
+    int deleteMenuById(Long menuId);
+
+    /**
+     * 鏍¢獙鑿滃崟鍚嶇О鏄惁鍞竴
+     *
+     * @param menu 鑿滃崟淇℃伅
+     * @return 缁撴灉
+     */
+    boolean checkMenuNameUnique(SysMenuBo menu);
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysNoticeService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysNoticeService.java
new file mode 100644
index 0000000..8ec999d
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysNoticeService.java
@@ -0,0 +1,67 @@
+package org.dromara.system.service;
+
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.system.domain.bo.SysNoticeBo;
+import org.dromara.system.domain.vo.SysNoticeVo;
+
+import java.util.List;
+
+/**
+ * 鍏憡 鏈嶅姟灞�
+ *
+ * @author Lion Li
+ */
+public interface ISysNoticeService {
+
+
+    TableDataInfo<SysNoticeVo> selectPageNoticeList(SysNoticeBo notice, PageQuery pageQuery);
+
+    /**
+     * 鏌ヨ鍏憡淇℃伅
+     *
+     * @param noticeId 鍏憡ID
+     * @return 鍏憡淇℃伅
+     */
+    SysNoticeVo selectNoticeById(Long noticeId);
+
+    /**
+     * 鏌ヨ鍏憡鍒楄〃
+     *
+     * @param notice 鍏憡淇℃伅
+     * @return 鍏憡闆嗗悎
+     */
+    List<SysNoticeVo> selectNoticeList(SysNoticeBo notice);
+
+    /**
+     * 鏂板鍏憡
+     *
+     * @param bo 鍏憡淇℃伅
+     * @return 缁撴灉
+     */
+    int insertNotice(SysNoticeBo bo);
+
+    /**
+     * 淇敼鍏憡
+     *
+     * @param bo 鍏憡淇℃伅
+     * @return 缁撴灉
+     */
+    int updateNotice(SysNoticeBo bo);
+
+    /**
+     * 鍒犻櫎鍏憡淇℃伅
+     *
+     * @param noticeId 鍏憡ID
+     * @return 缁撴灉
+     */
+    int deleteNoticeById(Long noticeId);
+
+    /**
+     * 鎵归噺鍒犻櫎鍏憡淇℃伅
+     *
+     * @param noticeIds 闇�瑕佸垹闄ょ殑鍏憡ID
+     * @return 缁撴灉
+     */
+    int deleteNoticeByIds(Long[] noticeIds);
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysOperLogService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysOperLogService.java
new file mode 100644
index 0000000..9573510
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysOperLogService.java
@@ -0,0 +1,54 @@
+package org.dromara.system.service;
+
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.system.domain.bo.SysOperLogBo;
+import org.dromara.system.domain.vo.SysOperLogVo;
+
+import java.util.List;
+
+/**
+ * 鎿嶄綔鏃ュ織 鏈嶅姟灞�
+ *
+ * @author Lion Li
+ */
+public interface ISysOperLogService {
+
+    TableDataInfo<SysOperLogVo> selectPageOperLogList(SysOperLogBo operLog, PageQuery pageQuery);
+
+    /**
+     * 鏂板鎿嶄綔鏃ュ織
+     *
+     * @param bo 鎿嶄綔鏃ュ織瀵硅薄
+     */
+    void insertOperlog(SysOperLogBo bo);
+
+    /**
+     * 鏌ヨ绯荤粺鎿嶄綔鏃ュ織闆嗗悎
+     *
+     * @param operLog 鎿嶄綔鏃ュ織瀵硅薄
+     * @return 鎿嶄綔鏃ュ織闆嗗悎
+     */
+    List<SysOperLogVo> selectOperLogList(SysOperLogBo operLog);
+
+    /**
+     * 鎵归噺鍒犻櫎绯荤粺鎿嶄綔鏃ュ織
+     *
+     * @param operIds 闇�瑕佸垹闄ょ殑鎿嶄綔鏃ュ織ID
+     * @return 缁撴灉
+     */
+    int deleteOperLogByIds(Long[] operIds);
+
+    /**
+     * 鏌ヨ鎿嶄綔鏃ュ織璇︾粏
+     *
+     * @param operId 鎿嶄綔ID
+     * @return 鎿嶄綔鏃ュ織瀵硅薄
+     */
+    SysOperLogVo selectOperLogById(Long operId);
+
+    /**
+     * 娓呯┖鎿嶄綔鏃ュ織
+     */
+    void cleanOperLog();
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysOssConfigService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysOssConfigService.java
new file mode 100644
index 0000000..a8bc57b
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysOssConfigService.java
@@ -0,0 +1,65 @@
+package org.dromara.system.service;
+
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.system.domain.bo.SysOssConfigBo;
+import org.dromara.system.domain.vo.SysOssConfigVo;
+
+import java.util.Collection;
+
+/**
+ * 瀵硅薄瀛樺偍閰嶇疆Service鎺ュ彛
+ *
+ * @author Lion Li
+ * @author 瀛よ垷鐑熼洦
+ * @date 2021-08-13
+ */
+public interface ISysOssConfigService {
+
+    /**
+     * 鍒濆鍖朞SS閰嶇疆
+     */
+    void init();
+
+    /**
+     * 鏌ヨ鍗曚釜
+     */
+    SysOssConfigVo queryById(Long ossConfigId);
+
+    /**
+     * 鏌ヨ鍒楄〃
+     */
+    TableDataInfo<SysOssConfigVo> queryPageList(SysOssConfigBo bo, PageQuery pageQuery);
+
+
+    /**
+     * 鏍规嵁鏂板涓氬姟瀵硅薄鎻掑叆瀵硅薄瀛樺偍閰嶇疆
+     *
+     * @param bo 瀵硅薄瀛樺偍閰嶇疆鏂板涓氬姟瀵硅薄
+     * @return
+     */
+    Boolean insertByBo(SysOssConfigBo bo);
+
+    /**
+     * 鏍规嵁缂栬緫涓氬姟瀵硅薄淇敼瀵硅薄瀛樺偍閰嶇疆
+     *
+     * @param bo 瀵硅薄瀛樺偍閰嶇疆缂栬緫涓氬姟瀵硅薄
+     * @return
+     */
+    Boolean updateByBo(SysOssConfigBo bo);
+
+    /**
+     * 鏍¢獙骞跺垹闄ゆ暟鎹�
+     *
+     * @param ids     涓婚敭闆嗗悎
+     * @param isValid 鏄惁鏍¢獙,true-鍒犻櫎鍓嶆牎楠�,false-涓嶆牎楠�
+     * @return
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     * 鍚敤鍋滅敤鐘舵��
+     */
+    int updateOssConfigStatus(SysOssConfigBo bo);
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysOssService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysOssService.java
new file mode 100644
index 0000000..000ecb4
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysOssService.java
@@ -0,0 +1,33 @@
+package org.dromara.system.service;
+
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.system.domain.bo.SysOssBo;
+import org.dromara.system.domain.vo.SysOssVo;
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 鏂囦欢涓婁紶 鏈嶅姟灞�
+ *
+ * @author Lion Li
+ */
+public interface ISysOssService {
+
+    TableDataInfo<SysOssVo> queryPageList(SysOssBo sysOss, PageQuery pageQuery);
+
+    List<SysOssVo> listByIds(Collection<Long> ossIds);
+
+    SysOssVo getById(Long ossId);
+
+    SysOssVo upload(MultipartFile file);
+
+    void download(Long ossId, HttpServletResponse response) throws IOException;
+
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysPermissionService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysPermissionService.java
new file mode 100644
index 0000000..0116df5
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysPermissionService.java
@@ -0,0 +1,28 @@
+package org.dromara.system.service;
+
+import java.util.Set;
+
+/**
+ * 鐢ㄦ埛鏉冮檺澶勭悊
+ *
+ * @author Lion Li
+ */
+public interface ISysPermissionService {
+
+    /**
+     * 鑾峰彇瑙掕壊鏁版嵁鏉冮檺
+     *
+     * @param userId  鐢ㄦ埛id
+     * @return 瑙掕壊鏉冮檺淇℃伅
+     */
+    Set<String> getRolePermission(Long userId);
+
+    /**
+     * 鑾峰彇鑿滃崟鏁版嵁鏉冮檺
+     *
+     * @param userId  鐢ㄦ埛id
+     * @return 鑿滃崟鏉冮檺淇℃伅
+     */
+    Set<String> getMenuPermission(Long userId);
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysPostService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysPostService.java
new file mode 100644
index 0000000..c6409c8
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysPostService.java
@@ -0,0 +1,106 @@
+package org.dromara.system.service;
+
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.system.domain.bo.SysPostBo;
+import org.dromara.system.domain.vo.SysPostVo;
+
+import java.util.List;
+
+/**
+ * 宀椾綅淇℃伅 鏈嶅姟灞�
+ *
+ * @author Lion Li
+ */
+public interface ISysPostService {
+
+
+    TableDataInfo<SysPostVo> selectPagePostList(SysPostBo post, PageQuery pageQuery);
+
+    /**
+     * 鏌ヨ宀椾綅淇℃伅闆嗗悎
+     *
+     * @param post 宀椾綅淇℃伅
+     * @return 宀椾綅鍒楄〃
+     */
+    List<SysPostVo> selectPostList(SysPostBo post);
+
+    /**
+     * 鏌ヨ鎵�鏈夊矖浣�
+     *
+     * @return 宀椾綅鍒楄〃
+     */
+    List<SysPostVo> selectPostAll();
+
+    /**
+     * 閫氳繃宀椾綅ID鏌ヨ宀椾綅淇℃伅
+     *
+     * @param postId 宀椾綅ID
+     * @return 瑙掕壊瀵硅薄淇℃伅
+     */
+    SysPostVo selectPostById(Long postId);
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鑾峰彇宀椾綅閫夋嫨妗嗗垪琛�
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 閫変腑宀椾綅ID鍒楄〃
+     */
+    List<Long> selectPostListByUserId(Long userId);
+
+    /**
+     * 鏍¢獙宀椾綅鍚嶇О
+     *
+     * @param post 宀椾綅淇℃伅
+     * @return 缁撴灉
+     */
+    boolean checkPostNameUnique(SysPostBo post);
+
+    /**
+     * 鏍¢獙宀椾綅缂栫爜
+     *
+     * @param post 宀椾綅淇℃伅
+     * @return 缁撴灉
+     */
+    boolean checkPostCodeUnique(SysPostBo post);
+
+    /**
+     * 閫氳繃宀椾綅ID鏌ヨ宀椾綅浣跨敤鏁伴噺
+     *
+     * @param postId 宀椾綅ID
+     * @return 缁撴灉
+     */
+    long countUserPostById(Long postId);
+
+    /**
+     * 鍒犻櫎宀椾綅淇℃伅
+     *
+     * @param postId 宀椾綅ID
+     * @return 缁撴灉
+     */
+    int deletePostById(Long postId);
+
+    /**
+     * 鎵归噺鍒犻櫎宀椾綅淇℃伅
+     *
+     * @param postIds 闇�瑕佸垹闄ょ殑宀椾綅ID
+     * @return 缁撴灉
+     */
+    int deletePostByIds(Long[] postIds);
+
+    /**
+     * 鏂板淇濆瓨宀椾綅淇℃伅
+     *
+     * @param bo 宀椾綅淇℃伅
+     * @return 缁撴灉
+     */
+    int insertPost(SysPostBo bo);
+
+    /**
+     * 淇敼淇濆瓨宀椾綅淇℃伅
+     *
+     * @param bo 宀椾綅淇℃伅
+     * @return 缁撴灉
+     */
+    int updatePost(SysPostBo bo);
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysRoleService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysRoleService.java
new file mode 100644
index 0000000..3e5a96c
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysRoleService.java
@@ -0,0 +1,181 @@
+package org.dromara.system.service;
+
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.system.domain.SysUserRole;
+import org.dromara.system.domain.bo.SysRoleBo;
+import org.dromara.system.domain.vo.SysRoleVo;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 瑙掕壊涓氬姟灞�
+ *
+ * @author Lion Li
+ */
+public interface ISysRoleService {
+
+
+    TableDataInfo<SysRoleVo> selectPageRoleList(SysRoleBo role, PageQuery pageQuery);
+
+    /**
+     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瑙掕壊鏁版嵁
+     *
+     * @param role 瑙掕壊淇℃伅
+     * @return 瑙掕壊鏁版嵁闆嗗悎淇℃伅
+     */
+    List<SysRoleVo> selectRoleList(SysRoleBo role);
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鏌ヨ瑙掕壊鍒楄〃
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 瑙掕壊鍒楄〃
+     */
+    List<SysRoleVo> selectRolesByUserId(Long userId);
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鏌ヨ瑙掕壊鏉冮檺
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 鏉冮檺鍒楄〃
+     */
+    Set<String> selectRolePermissionByUserId(Long userId);
+
+    /**
+     * 鏌ヨ鎵�鏈夎鑹�
+     *
+     * @return 瑙掕壊鍒楄〃
+     */
+    List<SysRoleVo> selectRoleAll();
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鑾峰彇瑙掕壊閫夋嫨妗嗗垪琛�
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 閫変腑瑙掕壊ID鍒楄〃
+     */
+    List<Long> selectRoleListByUserId(Long userId);
+
+    /**
+     * 閫氳繃瑙掕壊ID鏌ヨ瑙掕壊
+     *
+     * @param roleId 瑙掕壊ID
+     * @return 瑙掕壊瀵硅薄淇℃伅
+     */
+    SysRoleVo selectRoleById(Long roleId);
+
+    /**
+     * 鏍¢獙瑙掕壊鍚嶇О鏄惁鍞竴
+     *
+     * @param role 瑙掕壊淇℃伅
+     * @return 缁撴灉
+     */
+    boolean checkRoleNameUnique(SysRoleBo role);
+
+    /**
+     * 鏍¢獙瑙掕壊鏉冮檺鏄惁鍞竴
+     *
+     * @param role 瑙掕壊淇℃伅
+     * @return 缁撴灉
+     */
+    boolean checkRoleKeyUnique(SysRoleBo role);
+
+    /**
+     * 鏍¢獙瑙掕壊鏄惁鍏佽鎿嶄綔
+     *
+     * @param roleId 瑙掕壊ID
+     */
+    void checkRoleAllowed(Long roleId);
+
+    /**
+     * 鏍¢獙瑙掕壊鏄惁鏈夋暟鎹潈闄�
+     *
+     * @param roleId 瑙掕壊id
+     */
+    void checkRoleDataScope(Long roleId);
+
+    /**
+     * 閫氳繃瑙掕壊ID鏌ヨ瑙掕壊浣跨敤鏁伴噺
+     *
+     * @param roleId 瑙掕壊ID
+     * @return 缁撴灉
+     */
+    long countUserRoleByRoleId(Long roleId);
+
+    /**
+     * 鏂板淇濆瓨瑙掕壊淇℃伅
+     *
+     * @param bo 瑙掕壊淇℃伅
+     * @return 缁撴灉
+     */
+    int insertRole(SysRoleBo bo);
+
+    /**
+     * 淇敼淇濆瓨瑙掕壊淇℃伅
+     *
+     * @param bo 瑙掕壊淇℃伅
+     * @return 缁撴灉
+     */
+    int updateRole(SysRoleBo bo);
+
+    /**
+     * 淇敼瑙掕壊鐘舵��
+     *
+     * @param roleId 瑙掕壊ID
+     * @param status 瑙掕壊鐘舵��
+     * @return 缁撴灉
+     */
+    int updateRoleStatus(Long roleId, String status);
+
+    /**
+     * 淇敼鏁版嵁鏉冮檺淇℃伅
+     *
+     * @param bo 瑙掕壊淇℃伅
+     * @return 缁撴灉
+     */
+    int authDataScope(SysRoleBo bo);
+
+    /**
+     * 閫氳繃瑙掕壊ID鍒犻櫎瑙掕壊
+     *
+     * @param roleId 瑙掕壊ID
+     * @return 缁撴灉
+     */
+    int deleteRoleById(Long roleId);
+
+    /**
+     * 鎵归噺鍒犻櫎瑙掕壊淇℃伅
+     *
+     * @param roleIds 闇�瑕佸垹闄ょ殑瑙掕壊ID
+     * @return 缁撴灉
+     */
+    int deleteRoleByIds(Long[] roleIds);
+
+    /**
+     * 鍙栨秷鎺堟潈鐢ㄦ埛瑙掕壊
+     *
+     * @param userRole 鐢ㄦ埛鍜岃鑹插叧鑱斾俊鎭�
+     * @return 缁撴灉
+     */
+    int deleteAuthUser(SysUserRole userRole);
+
+    /**
+     * 鎵归噺鍙栨秷鎺堟潈鐢ㄦ埛瑙掕壊
+     *
+     * @param roleId  瑙掕壊ID
+     * @param userIds 闇�瑕佸彇娑堟巿鏉冪殑鐢ㄦ埛鏁版嵁ID
+     * @return 缁撴灉
+     */
+    int deleteAuthUsers(Long roleId, Long[] userIds);
+
+    /**
+     * 鎵归噺閫夋嫨鎺堟潈鐢ㄦ埛瑙掕壊
+     *
+     * @param roleId  瑙掕壊ID
+     * @param userIds 闇�瑕佸垹闄ょ殑鐢ㄦ埛鏁版嵁ID
+     * @return 缁撴灉
+     */
+    int insertAuthUsers(Long roleId, Long[] userIds);
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysTenantPackageService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysTenantPackageService.java
new file mode 100644
index 0000000..122ff40
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysTenantPackageService.java
@@ -0,0 +1,52 @@
+package org.dromara.system.service;
+
+import org.dromara.system.domain.vo.SysTenantPackageVo;
+import org.dromara.system.domain.bo.SysTenantPackageBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 绉熸埛濂楅Service鎺ュ彛
+ *
+ * @author Michelle.Chung
+ */
+public interface ISysTenantPackageService {
+
+    /**
+     * 鏌ヨ绉熸埛濂楅
+     */
+    SysTenantPackageVo queryById(Long packageId);
+
+    /**
+     * 鏌ヨ绉熸埛濂楅鍒楄〃
+     */
+    TableDataInfo<SysTenantPackageVo> queryPageList(SysTenantPackageBo bo, PageQuery pageQuery);
+
+    /**
+     * 鏌ヨ绉熸埛濂楅鍒楄〃
+     */
+    List<SysTenantPackageVo> queryList(SysTenantPackageBo bo);
+
+    /**
+     * 鏂板绉熸埛濂楅
+     */
+    Boolean insertByBo(SysTenantPackageBo bo);
+
+    /**
+     * 淇敼绉熸埛濂楅
+     */
+    Boolean updateByBo(SysTenantPackageBo bo);
+
+    /**
+     * 淇敼濂楅鐘舵��
+     */
+    int updatePackageStatus(SysTenantPackageBo bo);
+
+    /**
+     * 鏍¢獙骞舵壒閲忓垹闄ょ鎴峰椁愪俊鎭�
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysTenantService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysTenantService.java
new file mode 100644
index 0000000..f889f2b
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysTenantService.java
@@ -0,0 +1,82 @@
+package org.dromara.system.service;
+
+import org.dromara.system.domain.vo.SysTenantVo;
+import org.dromara.system.domain.bo.SysTenantBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 绉熸埛Service鎺ュ彛
+ *
+ * @author Michelle.Chung
+ */
+public interface ISysTenantService {
+
+    /**
+     * 鏌ヨ绉熸埛
+     */
+    SysTenantVo queryById(Long id);
+
+    /**
+     * 鍩轰簬绉熸埛ID鏌ヨ绉熸埛
+     */
+    SysTenantVo queryByTenantId(String tenantId);
+
+    /**
+     * 鏌ヨ绉熸埛鍒楄〃
+     */
+    TableDataInfo<SysTenantVo> queryPageList(SysTenantBo bo, PageQuery pageQuery);
+
+    /**
+     * 鏌ヨ绉熸埛鍒楄〃
+     */
+    List<SysTenantVo> queryList(SysTenantBo bo);
+
+    /**
+     * 鏂板绉熸埛
+     */
+    Boolean insertByBo(SysTenantBo bo);
+
+    /**
+     * 淇敼绉熸埛
+     */
+    Boolean updateByBo(SysTenantBo bo);
+
+    /**
+     * 淇敼绉熸埛鐘舵��
+     */
+    int updateTenantStatus(SysTenantBo bo);
+
+    /**
+     * 鏍¢獙绉熸埛鏄惁鍏佽鎿嶄綔
+     */
+    void checkTenantAllowed(String tenantId);
+
+    /**
+     * 鏍¢獙骞舵壒閲忓垹闄ょ鎴蜂俊鎭�
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     * 鏍¢獙浼佷笟鍚嶇О鏄惁鍞竴
+     */
+    boolean checkCompanyNameUnique(SysTenantBo bo);
+
+    /**
+     * 鏍¢獙璐﹀彿浣欓
+     */
+    boolean checkAccountBalance(String tenantId);
+
+    /**
+     * 鏍¢獙鏈夋晥鏈�
+     */
+    boolean checkExpireTime(String tenantId);
+
+    /**
+     * 鍚屾绉熸埛濂楅
+     */
+    Boolean syncTenantPackage(String tenantId, String packageId);
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java
new file mode 100644
index 0000000..cee5722
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java
@@ -0,0 +1,205 @@
+package org.dromara.system.service;
+
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.system.domain.bo.SysUserBo;
+import org.dromara.system.domain.vo.SysUserVo;
+
+import java.util.List;
+
+/**
+ * 鐢ㄦ埛 涓氬姟灞�
+ *
+ * @author Lion Li
+ */
+public interface ISysUserService {
+
+
+    TableDataInfo<SysUserVo> selectPageUserList(SysUserBo user, PageQuery pageQuery);
+
+    /**
+     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ鐢ㄦ埛鍒楄〃
+     *
+     * @param user 鐢ㄦ埛淇℃伅
+     * @return 鐢ㄦ埛淇℃伅闆嗗悎淇℃伅
+     */
+    List<SysUserVo> selectUserList(SysUserBo user);
+
+    /**
+     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ宸插垎閰嶇敤鎴疯鑹插垪琛�
+     *
+     * @param user 鐢ㄦ埛淇℃伅
+     * @return 鐢ㄦ埛淇℃伅闆嗗悎淇℃伅
+     */
+    TableDataInfo<SysUserVo> selectAllocatedList(SysUserBo user, PageQuery pageQuery);
+
+    /**
+     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ鏈垎閰嶇敤鎴疯鑹插垪琛�
+     *
+     * @param user 鐢ㄦ埛淇℃伅
+     * @return 鐢ㄦ埛淇℃伅闆嗗悎淇℃伅
+     */
+    TableDataInfo<SysUserVo> selectUnallocatedList(SysUserBo user, PageQuery pageQuery);
+
+    /**
+     * 閫氳繃鐢ㄦ埛鍚嶆煡璇㈢敤鎴�
+     *
+     * @param userName 鐢ㄦ埛鍚�
+     * @return 鐢ㄦ埛瀵硅薄淇℃伅
+     */
+    SysUserVo selectUserByUserName(String userName);
+
+    /**
+     * 閫氳繃鎵嬫満鍙锋煡璇㈢敤鎴�
+     *
+     * @param phonenumber 鎵嬫満鍙�
+     * @return 鐢ㄦ埛瀵硅薄淇℃伅
+     */
+    SysUserVo selectUserByPhonenumber(String phonenumber);
+
+    /**
+     * 閫氳繃鐢ㄦ埛ID鏌ヨ鐢ㄦ埛
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 鐢ㄦ埛瀵硅薄淇℃伅
+     */
+    SysUserVo selectUserById(Long userId);
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鏌ヨ鐢ㄦ埛鎵�灞炶鑹茬粍
+     *
+     * @param userName 鐢ㄦ埛鍚�
+     * @return 缁撴灉
+     */
+    String selectUserRoleGroup(String userName);
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鏌ヨ鐢ㄦ埛鎵�灞炲矖浣嶇粍
+     *
+     * @param userName 鐢ㄦ埛鍚�
+     * @return 缁撴灉
+     */
+    String selectUserPostGroup(String userName);
+
+    /**
+     * 鏍¢獙鐢ㄦ埛鍚嶇О鏄惁鍞竴
+     *
+     * @param user 鐢ㄦ埛淇℃伅
+     * @return 缁撴灉
+     */
+    boolean checkUserNameUnique(SysUserBo user);
+
+    /**
+     * 鏍¢獙鎵嬫満鍙风爜鏄惁鍞竴
+     *
+     * @param user 鐢ㄦ埛淇℃伅
+     * @return 缁撴灉
+     */
+    boolean checkPhoneUnique(SysUserBo user);
+
+    /**
+     * 鏍¢獙email鏄惁鍞竴
+     *
+     * @param user 鐢ㄦ埛淇℃伅
+     * @return 缁撴灉
+     */
+    boolean checkEmailUnique(SysUserBo user);
+
+    /**
+     * 鏍¢獙鐢ㄦ埛鏄惁鍏佽鎿嶄綔
+     *
+     * @param userId 鐢ㄦ埛ID
+     */
+    void checkUserAllowed(Long userId);
+
+    /**
+     * 鏍¢獙鐢ㄦ埛鏄惁鏈夋暟鎹潈闄�
+     *
+     * @param userId 鐢ㄦ埛id
+     */
+    void checkUserDataScope(Long userId);
+
+    /**
+     * 鏂板鐢ㄦ埛淇℃伅
+     *
+     * @param user 鐢ㄦ埛淇℃伅
+     * @return 缁撴灉
+     */
+    int insertUser(SysUserBo user);
+
+    /**
+     * 娉ㄥ唽鐢ㄦ埛淇℃伅
+     *
+     * @param user 鐢ㄦ埛淇℃伅
+     * @return 缁撴灉
+     */
+    boolean registerUser(SysUserBo user, String tenantId);
+
+    /**
+     * 淇敼鐢ㄦ埛淇℃伅
+     *
+     * @param user 鐢ㄦ埛淇℃伅
+     * @return 缁撴灉
+     */
+    int updateUser(SysUserBo user);
+
+    /**
+     * 鐢ㄦ埛鎺堟潈瑙掕壊
+     *
+     * @param userId  鐢ㄦ埛ID
+     * @param roleIds 瑙掕壊缁�
+     */
+    void insertUserAuth(Long userId, Long[] roleIds);
+
+    /**
+     * 淇敼鐢ㄦ埛鐘舵��
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @param status 甯愬彿鐘舵��
+     * @return 缁撴灉
+     */
+    int updateUserStatus(Long userId, String status);
+
+    /**
+     * 淇敼鐢ㄦ埛鍩烘湰淇℃伅
+     *
+     * @param user 鐢ㄦ埛淇℃伅
+     * @return 缁撴灉
+     */
+    int updateUserProfile(SysUserBo user);
+
+    /**
+     * 淇敼鐢ㄦ埛澶村儚
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @param avatar 澶村儚鍦板潃
+     * @return 缁撴灉
+     */
+    boolean updateUserAvatar(Long userId, Long avatar);
+
+    /**
+     * 閲嶇疆鐢ㄦ埛瀵嗙爜
+     *
+     * @param userId   鐢ㄦ埛ID
+     * @param password 瀵嗙爜
+     * @return 缁撴灉
+     */
+    int resetUserPwd(Long userId, String password);
+
+    /**
+     * 閫氳繃鐢ㄦ埛ID鍒犻櫎鐢ㄦ埛
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 缁撴灉
+     */
+    int deleteUserById(Long userId);
+
+    /**
+     * 鎵归噺鍒犻櫎鐢ㄦ埛淇℃伅
+     *
+     * @param userIds 闇�瑕佸垹闄ょ殑鐢ㄦ埛ID
+     * @return 缁撴灉
+     */
+    int deleteUserByIds(Long[] userIds);
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysConfigServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysConfigServiceImpl.java
new file mode 100644
index 0000000..5eabb17
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysConfigServiceImpl.java
@@ -0,0 +1,216 @@
+package org.dromara.system.service.impl;
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.dromara.common.core.constant.CacheNames;
+import org.dromara.common.core.constant.UserConstants;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.service.ConfigService;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.redis.utils.CacheUtils;
+import org.dromara.common.tenant.helper.TenantHelper;
+import org.dromara.system.domain.SysConfig;
+import org.dromara.system.domain.bo.SysConfigBo;
+import org.dromara.system.domain.vo.SysConfigVo;
+import org.dromara.system.mapper.SysConfigMapper;
+import org.dromara.system.service.ISysConfigService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.cache.annotation.CachePut;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 鍙傛暟閰嶇疆 鏈嶅姟灞傚疄鐜�
+ *
+ * @author Lion Li
+ */
+@RequiredArgsConstructor
+@Service
+public class SysConfigServiceImpl implements ISysConfigService, ConfigService {
+
+    private final SysConfigMapper baseMapper;
+
+    @Override
+    public TableDataInfo<SysConfigVo> selectPageConfigList(SysConfigBo config, PageQuery pageQuery) {
+        LambdaQueryWrapper<SysConfig> lqw = buildQueryWrapper(config);
+        Page<SysConfigVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(page);
+    }
+
+    /**
+     * 鏌ヨ鍙傛暟閰嶇疆淇℃伅
+     *
+     * @param configId 鍙傛暟閰嶇疆ID
+     * @return 鍙傛暟閰嶇疆淇℃伅
+     */
+    @Override
+    @DS("master")
+    public SysConfigVo selectConfigById(Long configId) {
+        return baseMapper.selectVoById(configId);
+    }
+
+    /**
+     * 鏍规嵁閿悕鏌ヨ鍙傛暟閰嶇疆淇℃伅
+     *
+     * @param configKey 鍙傛暟key
+     * @return 鍙傛暟閿��
+     */
+    @Cacheable(cacheNames = CacheNames.SYS_CONFIG, key = "#configKey")
+    @Override
+    public String selectConfigByKey(String configKey) {
+        SysConfig retConfig = baseMapper.selectOne(new LambdaQueryWrapper<SysConfig>()
+            .eq(SysConfig::getConfigKey, configKey));
+        if (ObjectUtil.isNotNull(retConfig)) {
+            return retConfig.getConfigValue();
+        }
+        return StringUtils.EMPTY;
+    }
+
+    /**
+     * 鑾峰彇娉ㄥ唽寮�鍏�
+     * @param tenantId 绉熸埛id
+     * @return true寮�鍚紝false鍏抽棴
+     */
+    @Override
+    public boolean selectRegisterEnabled(String tenantId) {
+        SysConfig retConfig = baseMapper.selectOne(new LambdaQueryWrapper<SysConfig>()
+            .eq(SysConfig::getConfigKey, "sys.account.registerUser")
+            .eq(TenantHelper.isEnable(),SysConfig::getTenantId, tenantId));
+        if (ObjectUtil.isNull(retConfig)) {
+            return false;
+        }
+        return Convert.toBool(retConfig.getConfigValue());
+    }
+
+    /**
+     * 鏌ヨ鍙傛暟閰嶇疆鍒楄〃
+     *
+     * @param config 鍙傛暟閰嶇疆淇℃伅
+     * @return 鍙傛暟閰嶇疆闆嗗悎
+     */
+    @Override
+    public List<SysConfigVo> selectConfigList(SysConfigBo config) {
+        LambdaQueryWrapper<SysConfig> lqw = buildQueryWrapper(config);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<SysConfig> buildQueryWrapper(SysConfigBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<SysConfig> lqw = Wrappers.lambdaQuery();
+        lqw.like(StringUtils.isNotBlank(bo.getConfigName()), SysConfig::getConfigName, bo.getConfigName());
+        lqw.eq(StringUtils.isNotBlank(bo.getConfigType()), SysConfig::getConfigType, bo.getConfigType());
+        lqw.like(StringUtils.isNotBlank(bo.getConfigKey()), SysConfig::getConfigKey, bo.getConfigKey());
+        lqw.between(params.get("beginTime") != null && params.get("endTime") != null,
+            SysConfig::getCreateTime, params.get("beginTime"), params.get("endTime"));
+        return lqw;
+    }
+
+    /**
+     * 鏂板鍙傛暟閰嶇疆
+     *
+     * @param bo 鍙傛暟閰嶇疆淇℃伅
+     * @return 缁撴灉
+     */
+    @CachePut(cacheNames = CacheNames.SYS_CONFIG, key = "#bo.configKey")
+    @Override
+    public String insertConfig(SysConfigBo bo) {
+        SysConfig config = MapstructUtils.convert(bo, SysConfig.class);
+        int row = baseMapper.insert(config);
+        if (row > 0) {
+            return config.getConfigValue();
+        }
+        throw new ServiceException("鎿嶄綔澶辫触");
+    }
+
+    /**
+     * 淇敼鍙傛暟閰嶇疆
+     *
+     * @param bo 鍙傛暟閰嶇疆淇℃伅
+     * @return 缁撴灉
+     */
+    @CachePut(cacheNames = CacheNames.SYS_CONFIG, key = "#bo.configKey")
+    @Override
+    public String updateConfig(SysConfigBo bo) {
+        int row = 0;
+        SysConfig config = MapstructUtils.convert(bo, SysConfig.class);
+        if (config.getConfigId() != null) {
+            SysConfig temp = baseMapper.selectById(config.getConfigId());
+            if (!StringUtils.equals(temp.getConfigKey(), config.getConfigKey())) {
+                CacheUtils.evict(CacheNames.SYS_CONFIG, temp.getConfigKey());
+            }
+            row = baseMapper.updateById(config);
+        } else {
+            row = baseMapper.update(config, new LambdaQueryWrapper<SysConfig>()
+                .eq(SysConfig::getConfigKey, config.getConfigKey()));
+        }
+        if (row > 0) {
+            return config.getConfigValue();
+        }
+        throw new ServiceException("鎿嶄綔澶辫触");
+    }
+
+    /**
+     * 鎵归噺鍒犻櫎鍙傛暟淇℃伅
+     *
+     * @param configIds 闇�瑕佸垹闄ょ殑鍙傛暟ID
+     */
+    @Override
+    public void deleteConfigByIds(Long[] configIds) {
+        for (Long configId : configIds) {
+            SysConfig config = baseMapper.selectById(configId);
+            if (StringUtils.equals(UserConstants.YES, config.getConfigType())) {
+                throw new ServiceException(String.format("鍐呯疆鍙傛暟銆�%1$s銆戜笉鑳藉垹闄� ", config.getConfigKey()));
+            }
+            CacheUtils.evict(CacheNames.SYS_CONFIG, config.getConfigKey());
+        }
+        baseMapper.deleteBatchIds(Arrays.asList(configIds));
+    }
+
+    /**
+     * 閲嶇疆鍙傛暟缂撳瓨鏁版嵁
+     */
+    @Override
+    public void resetConfigCache() {
+        CacheUtils.clear(CacheNames.SYS_CONFIG);
+    }
+
+    /**
+     * 鏍¢獙鍙傛暟閿悕鏄惁鍞竴
+     *
+     * @param config 鍙傛暟閰嶇疆淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    public boolean checkConfigKeyUnique(SysConfigBo config) {
+        long configId = ObjectUtil.isNull(config.getConfigId()) ? -1L : config.getConfigId();
+        SysConfig info = baseMapper.selectOne(new LambdaQueryWrapper<SysConfig>().eq(SysConfig::getConfigKey, config.getConfigKey()));
+        if (ObjectUtil.isNotNull(info) && info.getConfigId() != configId) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 鏍规嵁鍙傛暟 key 鑾峰彇鍙傛暟鍊�
+     *
+     * @param configKey 鍙傛暟 key
+     * @return 鍙傛暟鍊�
+     */
+    @Override
+    public String getConfigValue(String configKey) {
+        return SpringUtils.getAopProxy(this).selectConfigByKey(configKey);
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDataScopeServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDataScopeServiceImpl.java
new file mode 100644
index 0000000..9c5a212
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDataScopeServiceImpl.java
@@ -0,0 +1,61 @@
+package org.dromara.system.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.convert.Convert;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import org.dromara.system.domain.SysDept;
+import org.dromara.common.mybatis.helper.DataBaseHelper;
+import org.dromara.common.core.utils.StreamUtils;
+import org.dromara.system.domain.SysRoleDept;
+import org.dromara.system.mapper.SysDeptMapper;
+import org.dromara.system.mapper.SysRoleDeptMapper;
+import org.dromara.system.service.ISysDataScopeService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 鏁版嵁鏉冮檺 瀹炵幇
+ * <p>
+ * 娉ㄦ剰: 姝ervice鍐呬笉鍏佽璋冪敤鏍囨敞`鏁版嵁鏉冮檺`娉ㄨВ鐨勬柟娉�
+ * 渚嬪: deptMapper.selectList 姝� selectList 鏂规硶鏍囨敞浜哷鏁版嵁鏉冮檺`娉ㄨВ 浼氬嚭鐜板惊鐜В鏋愮殑闂
+ *
+ * @author Lion Li
+ */
+@RequiredArgsConstructor
+@Service("sdss")
+public class SysDataScopeServiceImpl implements ISysDataScopeService {
+
+    private final SysRoleDeptMapper roleDeptMapper;
+    private final SysDeptMapper deptMapper;
+
+    @Override
+    public String getRoleCustom(Long roleId) {
+        List<SysRoleDept> list = roleDeptMapper.selectList(
+            new LambdaQueryWrapper<SysRoleDept>()
+                .select(SysRoleDept::getDeptId)
+                .eq(SysRoleDept::getRoleId, roleId));
+        if (CollUtil.isNotEmpty(list)) {
+            return StreamUtils.join(list, rd -> Convert.toStr(rd.getDeptId()));
+        }
+        return null;
+    }
+
+    @Override
+    public String getDeptAndChild(Long deptId) {
+        List<SysDept> deptList = deptMapper.selectList(new LambdaQueryWrapper<SysDept>()
+            .select(SysDept::getDeptId)
+            .apply(DataBaseHelper.findInSet(deptId, "ancestors")));
+        List<Long> ids = StreamUtils.toList(deptList, SysDept::getDeptId);
+        ids.add(deptId);
+        List<SysDept> list = deptMapper.selectList(new LambdaQueryWrapper<SysDept>()
+            .select(SysDept::getDeptId)
+            .in(SysDept::getDeptId, ids));
+        if (CollUtil.isNotEmpty(list)) {
+            return StreamUtils.join(list, d -> Convert.toStr(d.getDeptId()));
+        }
+        return null;
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java
new file mode 100644
index 0000000..36680e3
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java
@@ -0,0 +1,325 @@
+package org.dromara.system.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.lang.tree.Tree;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import org.dromara.common.core.constant.CacheNames;
+import org.dromara.common.core.constant.UserConstants;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.service.DeptService;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.core.utils.TreeBuildUtils;
+import org.dromara.common.mybatis.helper.DataBaseHelper;
+import org.dromara.common.redis.utils.CacheUtils;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.system.domain.SysDept;
+import org.dromara.system.domain.SysRole;
+import org.dromara.system.domain.SysUser;
+import org.dromara.system.domain.bo.SysDeptBo;
+import org.dromara.system.domain.vo.SysDeptVo;
+import org.dromara.system.mapper.SysDeptMapper;
+import org.dromara.system.mapper.SysRoleMapper;
+import org.dromara.system.mapper.SysUserMapper;
+import org.dromara.system.service.ISysDeptService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 閮ㄩ棬绠$悊 鏈嶅姟瀹炵幇
+ *
+ * @author Lion Li
+ */
+@RequiredArgsConstructor
+@Service
+public class SysDeptServiceImpl implements ISysDeptService, DeptService {
+
+    private final SysDeptMapper baseMapper;
+    private final SysRoleMapper roleMapper;
+    private final SysUserMapper userMapper;
+
+    /**
+     * 鏌ヨ閮ㄩ棬绠$悊鏁版嵁
+     *
+     * @param dept 閮ㄩ棬淇℃伅
+     * @return 閮ㄩ棬淇℃伅闆嗗悎
+     */
+    @Override
+    public List<SysDeptVo> selectDeptList(SysDeptBo dept) {
+        LambdaQueryWrapper<SysDept> lqw = buildQueryWrapper(dept);
+        return baseMapper.selectDeptList(lqw);
+    }
+
+    /**
+     * 鏌ヨ閮ㄩ棬鏍戠粨鏋勪俊鎭�
+     *
+     * @param bo 閮ㄩ棬淇℃伅
+     * @return 閮ㄩ棬鏍戜俊鎭泦鍚�
+     */
+    @Override
+    public List<Tree<Long>> selectDeptTreeList(SysDeptBo bo) {
+        LambdaQueryWrapper<SysDept> lqw = buildQueryWrapper(bo);
+        List<SysDept> depts = baseMapper.selectList(lqw);
+        return buildDeptTreeSelect(depts);
+    }
+
+    private LambdaQueryWrapper<SysDept> buildQueryWrapper(SysDeptBo bo) {
+        LambdaQueryWrapper<SysDept> lqw = Wrappers.lambdaQuery();
+        lqw.eq(SysDept::getDelFlag, "0");
+        lqw.eq(ObjectUtil.isNotNull(bo.getDeptId()), SysDept::getDeptId, bo.getDeptId());
+        lqw.eq(ObjectUtil.isNotNull(bo.getParentId()), SysDept::getParentId, bo.getParentId());
+        lqw.like(StringUtils.isNotBlank(bo.getDeptName()), SysDept::getDeptName, bo.getDeptName());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysDept::getStatus, bo.getStatus());
+        lqw.orderByAsc(SysDept::getParentId);
+        lqw.orderByAsc(SysDept::getOrderNum);
+        return lqw;
+    }
+
+    /**
+     * 鏋勫缓鍓嶇鎵�闇�瑕佷笅鎷夋爲缁撴瀯
+     *
+     * @param depts 閮ㄩ棬鍒楄〃
+     * @return 涓嬫媺鏍戠粨鏋勫垪琛�
+     */
+    @Override
+    public List<Tree<Long>> buildDeptTreeSelect(List<SysDept> depts) {
+        if (CollUtil.isEmpty(depts)) {
+            return CollUtil.newArrayList();
+        }
+        return TreeBuildUtils.build(depts, (dept, tree) ->
+            tree.setId(dept.getDeptId())
+                .setParentId(dept.getParentId())
+                .setName(dept.getDeptName())
+                .setWeight(dept.getOrderNum()));
+    }
+
+    /**
+     * 鏍规嵁瑙掕壊ID鏌ヨ閮ㄩ棬鏍戜俊鎭�
+     *
+     * @param roleId 瑙掕壊ID
+     * @return 閫変腑閮ㄩ棬鍒楄〃
+     */
+    @Override
+    public List<Long> selectDeptListByRoleId(Long roleId) {
+        SysRole role = roleMapper.selectById(roleId);
+        return baseMapper.selectDeptListByRoleId(roleId, role.getDeptCheckStrictly());
+    }
+
+    /**
+     * 鏍规嵁閮ㄩ棬ID鏌ヨ淇℃伅
+     *
+     * @param deptId 閮ㄩ棬ID
+     * @return 閮ㄩ棬淇℃伅
+     */
+    @Cacheable(cacheNames = CacheNames.SYS_DEPT, key = "#deptId")
+    @Override
+    public SysDeptVo selectDeptById(Long deptId) {
+        SysDeptVo dept = baseMapper.selectVoById(deptId);
+        if (ObjectUtil.isNull(dept)) {
+            return null;
+        }
+        SysDeptVo parentDept = baseMapper.selectVoOne(new LambdaQueryWrapper<SysDept>()
+            .select(SysDept::getDeptName).eq(SysDept::getDeptId, dept.getParentId()));
+        dept.setParentName(ObjectUtil.isNotNull(parentDept) ? parentDept.getDeptName() : null);
+        return dept;
+    }
+
+    /**
+     * 閫氳繃閮ㄩ棬ID鏌ヨ閮ㄩ棬鍚嶇О
+     *
+     * @param deptIds 閮ㄩ棬ID涓查�楀彿鍒嗛殧
+     * @return 閮ㄩ棬鍚嶇О涓查�楀彿鍒嗛殧
+     */
+    @Override
+    public String selectDeptNameByIds(String deptIds) {
+        List<String> list = new ArrayList<>();
+        for (Long id : StringUtils.splitTo(deptIds, Convert::toLong)) {
+            SysDeptVo vo = SpringUtils.getAopProxy(this).selectDeptById(id);
+            if (ObjectUtil.isNotNull(vo)) {
+                list.add(vo.getDeptName());
+            }
+        }
+        return String.join(StringUtils.SEPARATOR, list);
+    }
+
+    /**
+     * 鏍规嵁ID鏌ヨ鎵�鏈夊瓙閮ㄩ棬鏁帮紙姝e父鐘舵�侊級
+     *
+     * @param deptId 閮ㄩ棬ID
+     * @return 瀛愰儴闂ㄦ暟
+     */
+    @Override
+    public long selectNormalChildrenDeptById(Long deptId) {
+        return baseMapper.selectCount(new LambdaQueryWrapper<SysDept>()
+            .eq(SysDept::getStatus, UserConstants.DEPT_NORMAL)
+            .apply(DataBaseHelper.findInSet(deptId, "ancestors")));
+    }
+
+    /**
+     * 鏄惁瀛樺湪瀛愯妭鐐�
+     *
+     * @param deptId 閮ㄩ棬ID
+     * @return 缁撴灉
+     */
+    @Override
+    public boolean hasChildByDeptId(Long deptId) {
+        return baseMapper.exists(new LambdaQueryWrapper<SysDept>()
+            .eq(SysDept::getParentId, deptId));
+    }
+
+    /**
+     * 鏌ヨ閮ㄩ棬鏄惁瀛樺湪鐢ㄦ埛
+     *
+     * @param deptId 閮ㄩ棬ID
+     * @return 缁撴灉 true 瀛樺湪 false 涓嶅瓨鍦�
+     */
+    @Override
+    public boolean checkDeptExistUser(Long deptId) {
+        return userMapper.exists(new LambdaQueryWrapper<SysUser>()
+            .eq(SysUser::getDeptId, deptId));
+    }
+
+    /**
+     * 鏍¢獙閮ㄩ棬鍚嶇О鏄惁鍞竴
+     *
+     * @param dept 閮ㄩ棬淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    public boolean checkDeptNameUnique(SysDeptBo dept) {
+        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysDept>()
+            .eq(SysDept::getDeptName, dept.getDeptName())
+            .eq(SysDept::getParentId, dept.getParentId())
+            .ne(ObjectUtil.isNotNull(dept.getDeptId()), SysDept::getDeptId, dept.getDeptId()));
+        return !exist;
+    }
+
+    /**
+     * 鏍¢獙閮ㄩ棬鏄惁鏈夋暟鎹潈闄�
+     *
+     * @param deptId 閮ㄩ棬id
+     */
+    @Override
+    public void checkDeptDataScope(Long deptId) {
+        if (ObjectUtil.isNull(deptId)) {
+            return;
+        }
+        if (LoginHelper.isSuperAdmin()) {
+            return;
+        }
+        SysDeptVo dept = baseMapper.selectDeptById(deptId);
+        if (ObjectUtil.isNull(dept)) {
+            throw new ServiceException("娌℃湁鏉冮檺璁块棶閮ㄩ棬鏁版嵁锛�");
+        }
+    }
+
+    /**
+     * 鏂板淇濆瓨閮ㄩ棬淇℃伅
+     *
+     * @param bo 閮ㄩ棬淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    public int insertDept(SysDeptBo bo) {
+        SysDept info = baseMapper.selectById(bo.getParentId());
+        // 濡傛灉鐖惰妭鐐逛笉涓烘甯哥姸鎬�,鍒欎笉鍏佽鏂板瀛愯妭鐐�
+        if (!UserConstants.DEPT_NORMAL.equals(info.getStatus())) {
+            throw new ServiceException("閮ㄩ棬鍋滅敤锛屼笉鍏佽鏂板");
+        }
+        SysDept dept = MapstructUtils.convert(bo, SysDept.class);
+        dept.setAncestors(info.getAncestors() + StringUtils.SEPARATOR + dept.getParentId());
+        return baseMapper.insert(dept);
+    }
+
+    /**
+     * 淇敼淇濆瓨閮ㄩ棬淇℃伅
+     *
+     * @param bo 閮ㄩ棬淇℃伅
+     * @return 缁撴灉
+     */
+    @CacheEvict(cacheNames = CacheNames.SYS_DEPT, key = "#bo.deptId")
+    @Override
+    public int updateDept(SysDeptBo bo) {
+        SysDept dept = MapstructUtils.convert(bo, SysDept.class);
+        SysDept oldDept = baseMapper.selectById(dept.getDeptId());
+        if (!oldDept.getParentId().equals(dept.getParentId())) {
+            // 濡傛灉鏄柊鐖堕儴闂� 鍒欐牎楠屾槸鍚﹀叿鏈夋柊鐖堕儴闂ㄦ潈闄� 閬垮厤瓒婃潈
+            this.checkDeptDataScope(dept.getParentId());
+            SysDept newParentDept = baseMapper.selectById(dept.getParentId());
+            if (ObjectUtil.isNotNull(newParentDept) && ObjectUtil.isNotNull(oldDept)) {
+                String newAncestors = newParentDept.getAncestors() + StringUtils.SEPARATOR + newParentDept.getDeptId();
+                String oldAncestors = oldDept.getAncestors();
+                dept.setAncestors(newAncestors);
+                updateDeptChildren(dept.getDeptId(), newAncestors, oldAncestors);
+            }
+        }
+        int result = baseMapper.updateById(dept);
+        if (UserConstants.DEPT_NORMAL.equals(dept.getStatus()) && StringUtils.isNotEmpty(dept.getAncestors())
+            && !StringUtils.equals(UserConstants.DEPT_NORMAL, dept.getAncestors())) {
+            // 濡傛灉璇ラ儴闂ㄦ槸鍚敤鐘舵�侊紝鍒欏惎鐢ㄨ閮ㄩ棬鐨勬墍鏈変笂绾ч儴闂�
+            updateParentDeptStatusNormal(dept);
+        }
+        return result;
+    }
+
+    /**
+     * 淇敼璇ラ儴闂ㄧ殑鐖剁骇閮ㄩ棬鐘舵��
+     *
+     * @param dept 褰撳墠閮ㄩ棬
+     */
+    private void updateParentDeptStatusNormal(SysDept dept) {
+        String ancestors = dept.getAncestors();
+        Long[] deptIds = Convert.toLongArray(ancestors);
+        baseMapper.update(null, new LambdaUpdateWrapper<SysDept>()
+            .set(SysDept::getStatus, UserConstants.DEPT_NORMAL)
+            .in(SysDept::getDeptId, Arrays.asList(deptIds)));
+    }
+
+    /**
+     * 淇敼瀛愬厓绱犲叧绯�
+     *
+     * @param deptId       琚慨鏀圭殑閮ㄩ棬ID
+     * @param newAncestors 鏂扮殑鐖禝D闆嗗悎
+     * @param oldAncestors 鏃х殑鐖禝D闆嗗悎
+     */
+    private void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors) {
+        List<SysDept> children = baseMapper.selectList(new LambdaQueryWrapper<SysDept>()
+            .apply(DataBaseHelper.findInSet(deptId, "ancestors")));
+        List<SysDept> list = new ArrayList<>();
+        for (SysDept child : children) {
+            SysDept dept = new SysDept();
+            dept.setDeptId(child.getDeptId());
+            dept.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
+            list.add(dept);
+        }
+        if (CollUtil.isNotEmpty(list)) {
+            if (baseMapper.updateBatchById(list)) {
+                list.forEach(dept -> CacheUtils.evict(CacheNames.SYS_DEPT, dept.getDeptId()));
+            }
+        }
+    }
+
+    /**
+     * 鍒犻櫎閮ㄩ棬绠$悊淇℃伅
+     *
+     * @param deptId 閮ㄩ棬ID
+     * @return 缁撴灉
+     */
+    @CacheEvict(cacheNames = CacheNames.SYS_DEPT, key = "#deptId")
+    @Override
+    public int deleteDeptById(Long deptId) {
+        return baseMapper.deleteById(deptId);
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictDataServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictDataServiceImpl.java
new file mode 100644
index 0000000..bb03d0d
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictDataServiceImpl.java
@@ -0,0 +1,139 @@
+package org.dromara.system.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.dromara.common.core.constant.CacheNames;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.system.domain.SysDictData;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.redis.utils.CacheUtils;
+import org.dromara.system.domain.bo.SysDictDataBo;
+import org.dromara.system.domain.vo.SysDictDataVo;
+import org.dromara.system.mapper.SysDictDataMapper;
+import org.dromara.system.service.ISysDictDataService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.cache.annotation.CachePut;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 瀛楀吀 涓氬姟灞傚鐞�
+ *
+ * @author Lion Li
+ */
+@RequiredArgsConstructor
+@Service
+public class SysDictDataServiceImpl implements ISysDictDataService {
+
+    private final SysDictDataMapper baseMapper;
+
+    @Override
+    public TableDataInfo<SysDictDataVo> selectPageDictDataList(SysDictDataBo dictData, PageQuery pageQuery) {
+        LambdaQueryWrapper<SysDictData> lqw = buildQueryWrapper(dictData);
+        Page<SysDictDataVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(page);
+    }
+
+    /**
+     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瀛楀吀鏁版嵁
+     *
+     * @param dictData 瀛楀吀鏁版嵁淇℃伅
+     * @return 瀛楀吀鏁版嵁闆嗗悎淇℃伅
+     */
+    @Override
+    public List<SysDictDataVo> selectDictDataList(SysDictDataBo dictData) {
+        LambdaQueryWrapper<SysDictData> lqw = buildQueryWrapper(dictData);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<SysDictData> buildQueryWrapper(SysDictDataBo bo) {
+        LambdaQueryWrapper<SysDictData> lqw = Wrappers.lambdaQuery();
+        lqw.eq(bo.getDictSort() != null, SysDictData::getDictSort, bo.getDictSort());
+        lqw.like(StringUtils.isNotBlank(bo.getDictLabel()), SysDictData::getDictLabel, bo.getDictLabel());
+        lqw.eq(StringUtils.isNotBlank(bo.getDictType()), SysDictData::getDictType, bo.getDictType());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysDictData::getStatus, bo.getStatus());
+        lqw.orderByAsc(SysDictData::getDictSort);
+        return lqw;
+    }
+
+    /**
+     * 鏍规嵁瀛楀吀绫诲瀷鍜屽瓧鍏搁敭鍊兼煡璇㈠瓧鍏告暟鎹俊鎭�
+     *
+     * @param dictType  瀛楀吀绫诲瀷
+     * @param dictValue 瀛楀吀閿��
+     * @return 瀛楀吀鏍囩
+     */
+    @Override
+    public String selectDictLabel(String dictType, String dictValue) {
+        return baseMapper.selectOne(new LambdaQueryWrapper<SysDictData>()
+                .select(SysDictData::getDictLabel)
+                .eq(SysDictData::getDictType, dictType)
+                .eq(SysDictData::getDictValue, dictValue))
+            .getDictLabel();
+    }
+
+    /**
+     * 鏍规嵁瀛楀吀鏁版嵁ID鏌ヨ淇℃伅
+     *
+     * @param dictCode 瀛楀吀鏁版嵁ID
+     * @return 瀛楀吀鏁版嵁
+     */
+    @Override
+    public SysDictDataVo selectDictDataById(Long dictCode) {
+        return baseMapper.selectVoById(dictCode);
+    }
+
+    /**
+     * 鎵归噺鍒犻櫎瀛楀吀鏁版嵁淇℃伅
+     *
+     * @param dictCodes 闇�瑕佸垹闄ょ殑瀛楀吀鏁版嵁ID
+     */
+    @Override
+    public void deleteDictDataByIds(Long[] dictCodes) {
+        for (Long dictCode : dictCodes) {
+            SysDictData data = baseMapper.selectById(dictCode);
+            baseMapper.deleteById(dictCode);
+            CacheUtils.evict(CacheNames.SYS_DICT, data.getDictType());
+        }
+    }
+
+    /**
+     * 鏂板淇濆瓨瀛楀吀鏁版嵁淇℃伅
+     *
+     * @param bo 瀛楀吀鏁版嵁淇℃伅
+     * @return 缁撴灉
+     */
+    @CachePut(cacheNames = CacheNames.SYS_DICT, key = "#bo.dictType")
+    @Override
+    public List<SysDictDataVo> insertDictData(SysDictDataBo bo) {
+        SysDictData data = MapstructUtils.convert(bo, SysDictData.class);
+        int row = baseMapper.insert(data);
+        if (row > 0) {
+            return baseMapper.selectDictDataByType(data.getDictType());
+        }
+        throw new ServiceException("鎿嶄綔澶辫触");
+    }
+
+    /**
+     * 淇敼淇濆瓨瀛楀吀鏁版嵁淇℃伅
+     *
+     * @param bo 瀛楀吀鏁版嵁淇℃伅
+     * @return 缁撴灉
+     */
+    @CachePut(cacheNames = CacheNames.SYS_DICT, key = "#bo.dictType")
+    @Override
+    public List<SysDictDataVo> updateDictData(SysDictDataBo bo) {
+        SysDictData data = MapstructUtils.convert(bo, SysDictData.class);
+        int row = baseMapper.updateById(data);
+        if (row > 0) {
+            return baseMapper.selectDictDataByType(data.getDictType());
+        }
+        throw new ServiceException("鎿嶄綔澶辫触");
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictTypeServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictTypeServiceImpl.java
new file mode 100644
index 0000000..60431ec
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictTypeServiceImpl.java
@@ -0,0 +1,268 @@
+package org.dromara.system.service.impl;
+
+import cn.dev33.satoken.context.SaHolder;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.dromara.common.core.constant.CacheConstants;
+import org.dromara.common.core.constant.CacheNames;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.service.DictService;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.StreamUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.redis.utils.CacheUtils;
+import org.dromara.system.domain.SysDictData;
+import org.dromara.system.domain.SysDictType;
+import org.dromara.system.domain.bo.SysDictTypeBo;
+import org.dromara.system.domain.vo.SysDictDataVo;
+import org.dromara.system.domain.vo.SysDictTypeVo;
+import org.dromara.system.mapper.SysDictDataMapper;
+import org.dromara.system.mapper.SysDictTypeMapper;
+import org.dromara.system.service.ISysDictTypeService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.cache.annotation.CachePut;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 瀛楀吀 涓氬姟灞傚鐞�
+ *
+ * @author Lion Li
+ */
+@RequiredArgsConstructor
+@Service
+public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService {
+
+    private final SysDictTypeMapper baseMapper;
+    private final SysDictDataMapper dictDataMapper;
+
+    @Override
+    public TableDataInfo<SysDictTypeVo> selectPageDictTypeList(SysDictTypeBo dictType, PageQuery pageQuery) {
+        LambdaQueryWrapper<SysDictType> lqw = buildQueryWrapper(dictType);
+        Page<SysDictTypeVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(page);
+    }
+
+    /**
+     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瀛楀吀绫诲瀷
+     *
+     * @param dictType 瀛楀吀绫诲瀷淇℃伅
+     * @return 瀛楀吀绫诲瀷闆嗗悎淇℃伅
+     */
+    @Override
+    public List<SysDictTypeVo> selectDictTypeList(SysDictTypeBo dictType) {
+        LambdaQueryWrapper<SysDictType> lqw = buildQueryWrapper(dictType);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<SysDictType> buildQueryWrapper(SysDictTypeBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<SysDictType> lqw = Wrappers.lambdaQuery();
+        lqw.like(StringUtils.isNotBlank(bo.getDictName()), SysDictType::getDictName, bo.getDictName());
+        lqw.like(StringUtils.isNotBlank(bo.getDictType()), SysDictType::getDictType, bo.getDictType());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysDictType::getStatus, bo.getStatus());
+        lqw.between(params.get("beginTime") != null && params.get("endTime") != null,
+            SysDictType::getCreateTime, params.get("beginTime"), params.get("endTime"));
+        return lqw;
+    }
+
+    /**
+     * 鏍规嵁鎵�鏈夊瓧鍏哥被鍨�
+     *
+     * @return 瀛楀吀绫诲瀷闆嗗悎淇℃伅
+     */
+    @Override
+    public List<SysDictTypeVo> selectDictTypeAll() {
+        return baseMapper.selectVoList();
+    }
+
+    /**
+     * 鏍规嵁瀛楀吀绫诲瀷鏌ヨ瀛楀吀鏁版嵁
+     *
+     * @param dictType 瀛楀吀绫诲瀷
+     * @return 瀛楀吀鏁版嵁闆嗗悎淇℃伅
+     */
+    @Cacheable(cacheNames = CacheNames.SYS_DICT, key = "#dictType")
+    @Override
+    public List<SysDictDataVo> selectDictDataByType(String dictType) {
+        List<SysDictDataVo> dictDatas = dictDataMapper.selectDictDataByType(dictType);
+        if (CollUtil.isNotEmpty(dictDatas)) {
+            return dictDatas;
+        }
+        return null;
+    }
+
+    /**
+     * 鏍规嵁瀛楀吀绫诲瀷ID鏌ヨ淇℃伅
+     *
+     * @param dictId 瀛楀吀绫诲瀷ID
+     * @return 瀛楀吀绫诲瀷
+     */
+    @Override
+    public SysDictTypeVo selectDictTypeById(Long dictId) {
+        return baseMapper.selectVoById(dictId);
+    }
+
+    /**
+     * 鏍规嵁瀛楀吀绫诲瀷鏌ヨ淇℃伅
+     *
+     * @param dictType 瀛楀吀绫诲瀷
+     * @return 瀛楀吀绫诲瀷
+     */
+    @Cacheable(cacheNames = CacheNames.SYS_DICT, key = "#dictType")
+    @Override
+    public SysDictTypeVo selectDictTypeByType(String dictType) {
+        return baseMapper.selectVoById(new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getDictType, dictType));
+    }
+
+    /**
+     * 鎵归噺鍒犻櫎瀛楀吀绫诲瀷淇℃伅
+     *
+     * @param dictIds 闇�瑕佸垹闄ょ殑瀛楀吀ID
+     */
+    @Override
+    public void deleteDictTypeByIds(Long[] dictIds) {
+        for (Long dictId : dictIds) {
+            SysDictType dictType = baseMapper.selectById(dictId);
+            if (dictDataMapper.exists(new LambdaQueryWrapper<SysDictData>()
+                .eq(SysDictData::getDictType, dictType.getDictType()))) {
+                throw new ServiceException(String.format("%1$s宸插垎閰�,涓嶈兘鍒犻櫎", dictType.getDictName()));
+            }
+            CacheUtils.evict(CacheNames.SYS_DICT, dictType.getDictType());
+        }
+        baseMapper.deleteBatchIds(Arrays.asList(dictIds));
+    }
+
+    /**
+     * 閲嶇疆瀛楀吀缂撳瓨鏁版嵁
+     */
+    @Override
+    public void resetDictCache() {
+        CacheUtils.clear(CacheNames.SYS_DICT);
+    }
+
+    /**
+     * 鏂板淇濆瓨瀛楀吀绫诲瀷淇℃伅
+     *
+     * @param bo 瀛楀吀绫诲瀷淇℃伅
+     * @return 缁撴灉
+     */
+    @CachePut(cacheNames = CacheNames.SYS_DICT, key = "#bo.dictType")
+    @Override
+    public List<SysDictTypeVo> insertDictType(SysDictTypeBo bo) {
+        SysDictType dict = MapstructUtils.convert(bo, SysDictType.class);
+        int row = baseMapper.insert(dict);
+        if (row > 0) {
+            return new ArrayList<>();
+        }
+        throw new ServiceException("鎿嶄綔澶辫触");
+    }
+
+    /**
+     * 淇敼淇濆瓨瀛楀吀绫诲瀷淇℃伅
+     *
+     * @param bo 瀛楀吀绫诲瀷淇℃伅
+     * @return 缁撴灉
+     */
+    @CachePut(cacheNames = CacheNames.SYS_DICT, key = "#bo.dictType")
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public List<SysDictDataVo> updateDictType(SysDictTypeBo bo) {
+        SysDictType dict = MapstructUtils.convert(bo, SysDictType.class);
+        SysDictType oldDict = baseMapper.selectById(dict.getDictId());
+        dictDataMapper.update(null, new LambdaUpdateWrapper<SysDictData>()
+            .set(SysDictData::getDictType, dict.getDictType())
+            .eq(SysDictData::getDictType, oldDict.getDictType()));
+        int row = baseMapper.updateById(dict);
+        if (row > 0) {
+            CacheUtils.evict(CacheNames.SYS_DICT, oldDict.getDictType());
+            return dictDataMapper.selectDictDataByType(dict.getDictType());
+        }
+        throw new ServiceException("鎿嶄綔澶辫触");
+    }
+
+    /**
+     * 鏍¢獙瀛楀吀绫诲瀷绉版槸鍚﹀敮涓�
+     *
+     * @param dictType 瀛楀吀绫诲瀷
+     * @return 缁撴灉
+     */
+    @Override
+    public boolean checkDictTypeUnique(SysDictTypeBo dictType) {
+        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysDictType>()
+            .eq(SysDictType::getDictType, dictType.getDictType())
+            .ne(ObjectUtil.isNotNull(dictType.getDictId()), SysDictType::getDictId, dictType.getDictId()));
+        return !exist;
+    }
+
+    /**
+     * 鏍规嵁瀛楀吀绫诲瀷鍜屽瓧鍏稿�艰幏鍙栧瓧鍏告爣绛�
+     *
+     * @param dictType  瀛楀吀绫诲瀷
+     * @param dictValue 瀛楀吀鍊�
+     * @param separator 鍒嗛殧绗�
+     * @return 瀛楀吀鏍囩
+     */
+    @SuppressWarnings("unchecked cast")
+    @Override
+    public String getDictLabel(String dictType, String dictValue, String separator) {
+        // 浼樺厛浠庢湰鍦扮紦瀛樿幏鍙�
+        List<SysDictDataVo> datas = (List<SysDictDataVo>) SaHolder.getStorage().get(CacheConstants.SYS_DICT_KEY + dictType);
+        if (ObjectUtil.isNull(datas)) {
+            datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType);
+            SaHolder.getStorage().set(CacheConstants.SYS_DICT_KEY + dictType, datas);
+        }
+
+        Map<String, String> map = StreamUtils.toMap(datas, SysDictDataVo::getDictValue, SysDictDataVo::getDictLabel);
+        if (StringUtils.containsAny(dictValue, separator)) {
+            return Arrays.stream(dictValue.split(separator))
+                .map(v -> map.getOrDefault(v, StringUtils.EMPTY))
+                .collect(Collectors.joining(separator));
+        } else {
+            return map.getOrDefault(dictValue, StringUtils.EMPTY);
+        }
+    }
+
+    /**
+     * 鏍规嵁瀛楀吀绫诲瀷鍜屽瓧鍏告爣绛捐幏鍙栧瓧鍏稿��
+     *
+     * @param dictType  瀛楀吀绫诲瀷
+     * @param dictLabel 瀛楀吀鏍囩
+     * @param separator 鍒嗛殧绗�
+     * @return 瀛楀吀鍊�
+     */
+    @SuppressWarnings("unchecked cast")
+    @Override
+    public String getDictValue(String dictType, String dictLabel, String separator) {
+        // 浼樺厛浠庢湰鍦扮紦瀛樿幏鍙�
+        List<SysDictDataVo> datas = (List<SysDictDataVo>) SaHolder.getStorage().get(CacheConstants.SYS_DICT_KEY + dictType);
+        if (ObjectUtil.isNull(datas)) {
+            datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType);
+            SaHolder.getStorage().set(CacheConstants.SYS_DICT_KEY + dictType, datas);
+        }
+
+        Map<String, String> map = StreamUtils.toMap(datas, SysDictDataVo::getDictLabel, SysDictDataVo::getDictValue);
+        if (StringUtils.containsAny(dictLabel, separator)) {
+            return Arrays.stream(dictLabel.split(separator))
+                .map(l -> map.getOrDefault(l, StringUtils.EMPTY))
+                .collect(Collectors.joining(separator));
+        } else {
+            return map.getOrDefault(dictLabel, StringUtils.EMPTY);
+        }
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysLogininforServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysLogininforServiceImpl.java
new file mode 100644
index 0000000..d1c071e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysLogininforServiceImpl.java
@@ -0,0 +1,160 @@
+package org.dromara.system.service.impl;
+
+import cn.hutool.http.useragent.UserAgent;
+import cn.hutool.http.useragent.UserAgentUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.dromara.common.core.constant.Constants;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.log.event.LogininforEvent;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.core.utils.ServletUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.core.utils.ip.AddressUtils;
+import org.dromara.system.domain.SysLogininfor;
+import org.dromara.system.domain.bo.SysLogininforBo;
+import org.dromara.system.domain.vo.SysLogininforVo;
+import org.dromara.system.mapper.SysLogininforMapper;
+import org.dromara.system.service.ISysLogininforService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import jakarta.servlet.http.HttpServletRequest;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 绯荤粺璁块棶鏃ュ織鎯呭喌淇℃伅 鏈嶅姟灞傚鐞�
+ *
+ * @author Lion Li
+ */
+@RequiredArgsConstructor
+@Slf4j
+@Service
+public class SysLogininforServiceImpl implements ISysLogininforService {
+
+    private final SysLogininforMapper baseMapper;
+
+    /**
+     * 璁板綍鐧诲綍淇℃伅
+     *
+     * @param logininforEvent 鐧诲綍浜嬩欢
+     */
+    @Async
+    @EventListener
+    public void recordLogininfor(LogininforEvent logininforEvent) {
+        HttpServletRequest request = logininforEvent.getRequest();
+        final UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
+        final String ip = ServletUtils.getClientIP(request);
+
+        String address = AddressUtils.getRealAddressByIP(ip);
+        StringBuilder s = new StringBuilder();
+        s.append(getBlock(ip));
+        s.append(address);
+        s.append(getBlock(logininforEvent.getUsername()));
+        s.append(getBlock(logininforEvent.getStatus()));
+        s.append(getBlock(logininforEvent.getMessage()));
+        // 鎵撳嵃淇℃伅鍒版棩蹇�
+        log.info(s.toString(), logininforEvent.getArgs());
+        // 鑾峰彇瀹㈡埛绔搷浣滅郴缁�
+        String os = userAgent.getOs().getName();
+        // 鑾峰彇瀹㈡埛绔祻瑙堝櫒
+        String browser = userAgent.getBrowser().getName();
+        // 灏佽瀵硅薄
+        SysLogininforBo logininfor = new SysLogininforBo();
+        logininfor.setTenantId(logininforEvent.getTenantId());
+        logininfor.setUserName(logininforEvent.getUsername());
+        logininfor.setIpaddr(ip);
+        logininfor.setLoginLocation(address);
+        logininfor.setBrowser(browser);
+        logininfor.setOs(os);
+        logininfor.setMsg(logininforEvent.getMessage());
+        // 鏃ュ織鐘舵��
+        if (StringUtils.equalsAny(logininforEvent.getStatus(), Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) {
+            logininfor.setStatus(Constants.SUCCESS);
+        } else if (Constants.LOGIN_FAIL.equals(logininforEvent.getStatus())) {
+            logininfor.setStatus(Constants.FAIL);
+        }
+        // 鎻掑叆鏁版嵁
+        insertLogininfor(logininfor);
+    }
+
+    private String getBlock(Object msg) {
+        if (msg == null) {
+            msg = "";
+        }
+        return "[" + msg.toString() + "]";
+    }
+
+    @Override
+    public TableDataInfo<SysLogininforVo> selectPageLogininforList(SysLogininforBo logininfor, PageQuery pageQuery) {
+        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())
+            .between(params.get("beginTime") != null && params.get("endTime") != null,
+                SysLogininfor::getLoginTime, params.get("beginTime"), params.get("endTime"));
+        if (StringUtils.isBlank(pageQuery.getOrderByColumn())) {
+            pageQuery.setOrderByColumn("info_id");
+            pageQuery.setIsAsc("desc");
+        }
+        Page<SysLogininforVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(page);
+    }
+
+    /**
+     * 鏂板绯荤粺鐧诲綍鏃ュ織
+     *
+     * @param bo 璁块棶鏃ュ織瀵硅薄
+     */
+    @Override
+    public void insertLogininfor(SysLogininforBo bo) {
+        SysLogininfor logininfor = MapstructUtils.convert(bo, SysLogininfor.class);
+        logininfor.setLoginTime(new Date());
+        baseMapper.insert(logininfor);
+    }
+
+    /**
+     * 鏌ヨ绯荤粺鐧诲綍鏃ュ織闆嗗悎
+     *
+     * @param logininfor 璁块棶鏃ュ織瀵硅薄
+     * @return 鐧诲綍璁板綍闆嗗悎
+     */
+    @Override
+    public List<SysLogininforVo> selectLogininforList(SysLogininforBo logininfor) {
+        Map<String, Object> params = logininfor.getParams();
+        return baseMapper.selectVoList(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())
+            .between(params.get("beginTime") != null && params.get("endTime") != null,
+                SysLogininfor::getLoginTime, params.get("beginTime"), params.get("endTime"))
+            .orderByDesc(SysLogininfor::getInfoId));
+    }
+
+    /**
+     * 鎵归噺鍒犻櫎绯荤粺鐧诲綍鏃ュ織
+     *
+     * @param infoIds 闇�瑕佸垹闄ょ殑鐧诲綍鏃ュ織ID
+     * @return 缁撴灉
+     */
+    @Override
+    public int deleteLogininforByIds(Long[] infoIds) {
+        return baseMapper.deleteBatchIds(Arrays.asList(infoIds));
+    }
+
+    /**
+     * 娓呯┖绯荤粺鐧诲綍鏃ュ織
+     */
+    @Override
+    public void cleanLogininfor() {
+        baseMapper.delete(new LambdaQueryWrapper<>());
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
new file mode 100644
index 0000000..194b044
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
@@ -0,0 +1,365 @@
+package org.dromara.system.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.lang.tree.Tree;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import org.dromara.common.core.constant.UserConstants;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StreamUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.core.utils.TreeBuildUtils;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.system.domain.SysMenu;
+import org.dromara.system.domain.SysRole;
+import org.dromara.system.domain.SysRoleMenu;
+import org.dromara.system.domain.SysTenantPackage;
+import org.dromara.system.domain.bo.SysMenuBo;
+import org.dromara.system.domain.vo.MetaVo;
+import org.dromara.system.domain.vo.RouterVo;
+import org.dromara.system.domain.vo.SysMenuVo;
+import org.dromara.system.mapper.SysMenuMapper;
+import org.dromara.system.mapper.SysRoleMapper;
+import org.dromara.system.mapper.SysRoleMenuMapper;
+import org.dromara.system.mapper.SysTenantPackageMapper;
+import org.dromara.system.service.ISysMenuService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+/**
+ * 鑿滃崟 涓氬姟灞傚鐞�
+ *
+ * @author Lion Li
+ */
+@RequiredArgsConstructor
+@Service
+public class SysMenuServiceImpl implements ISysMenuService {
+
+    private final SysMenuMapper baseMapper;
+    private final SysRoleMapper roleMapper;
+    private final SysRoleMenuMapper roleMenuMapper;
+    private final SysTenantPackageMapper tenantPackageMapper;
+
+    /**
+     * 鏍规嵁鐢ㄦ埛鏌ヨ绯荤粺鑿滃崟鍒楄〃
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 鑿滃崟鍒楄〃
+     */
+    @Override
+    public List<SysMenuVo> selectMenuList(Long userId) {
+        return selectMenuList(new SysMenuBo(), userId);
+    }
+
+    /**
+     * 鏌ヨ绯荤粺鑿滃崟鍒楄〃
+     *
+     * @param menu 鑿滃崟淇℃伅
+     * @return 鑿滃崟鍒楄〃
+     */
+    @Override
+    public List<SysMenuVo> selectMenuList(SysMenuBo menu, Long userId) {
+        List<SysMenuVo> menuList;
+        // 绠$悊鍛樻樉绀烘墍鏈夎彍鍗曚俊鎭�
+        if (LoginHelper.isSuperAdmin(userId)) {
+            menuList = baseMapper.selectVoList(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));
+        } else {
+            QueryWrapper<SysMenu> wrapper = Wrappers.query();
+            wrapper.eq("sur.user_id", userId)
+                .like(StringUtils.isNotBlank(menu.getMenuName()), "m.menu_name", menu.getMenuName())
+                .eq(StringUtils.isNotBlank(menu.getVisible()), "m.visible", menu.getVisible())
+                .eq(StringUtils.isNotBlank(menu.getStatus()), "m.status", menu.getStatus())
+                .orderByAsc("m.parent_id")
+                .orderByAsc("m.order_num");
+            List<SysMenu> list = baseMapper.selectMenuListByUserId(wrapper);
+            menuList = MapstructUtils.convert(list, SysMenuVo.class);
+        }
+        return menuList;
+    }
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鏌ヨ鏉冮檺
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 鏉冮檺鍒楄〃
+     */
+    @Override
+    public Set<String> selectMenuPermsByUserId(Long userId) {
+        List<String> perms = baseMapper.selectMenuPermsByUserId(userId);
+        Set<String> permsSet = new HashSet<>();
+        for (String perm : perms) {
+            if (StringUtils.isNotEmpty(perm)) {
+                permsSet.addAll(StringUtils.splitList(perm.trim()));
+            }
+        }
+        return permsSet;
+    }
+
+    /**
+     * 鏍规嵁瑙掕壊ID鏌ヨ鏉冮檺
+     *
+     * @param roleId 瑙掕壊ID
+     * @return 鏉冮檺鍒楄〃
+     */
+    @Override
+    public Set<String> selectMenuPermsByRoleId(Long roleId) {
+        List<String> perms = baseMapper.selectMenuPermsByRoleId(roleId);
+        Set<String> permsSet = new HashSet<>();
+        for (String perm : perms) {
+            if (StringUtils.isNotEmpty(perm)) {
+                permsSet.addAll(StringUtils.splitList(perm.trim()));
+            }
+        }
+        return permsSet;
+    }
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鏌ヨ鑿滃崟
+     *
+     * @param userId 鐢ㄦ埛鍚嶇О
+     * @return 鑿滃崟鍒楄〃
+     */
+    @Override
+    public List<SysMenu> selectMenuTreeByUserId(Long userId) {
+        List<SysMenu> menus;
+        if (LoginHelper.isSuperAdmin(userId)) {
+            menus = baseMapper.selectMenuTreeAll();
+        } else {
+            menus = baseMapper.selectMenuTreeByUserId(userId);
+        }
+        return getChildPerms(menus, 0);
+    }
+
+    /**
+     * 鏍规嵁瑙掕壊ID鏌ヨ鑿滃崟鏍戜俊鎭�
+     *
+     * @param roleId 瑙掕壊ID
+     * @return 閫変腑鑿滃崟鍒楄〃
+     */
+    @Override
+    public List<Long> selectMenuListByRoleId(Long roleId) {
+        SysRole role = roleMapper.selectById(roleId);
+        return baseMapper.selectMenuListByRoleId(roleId, role.getMenuCheckStrictly());
+    }
+
+    /**
+     * 鏍规嵁绉熸埛濂楅ID鏌ヨ鑿滃崟鏍戜俊鎭�
+     *
+     * @param packageId 绉熸埛濂楅ID
+     * @return 閫変腑鑿滃崟鍒楄〃
+     */
+    @Override
+    public List<Long> selectMenuListByPackageId(Long packageId) {
+        SysTenantPackage tenantPackage = tenantPackageMapper.selectById(packageId);
+        List<Long> menuIds = StringUtils.splitTo(tenantPackage.getMenuIds(), Convert::toLong);
+        if (CollUtil.isEmpty(menuIds)) {
+            return List.of();
+        }
+        List<Long> parentIds = null;
+        if (tenantPackage.getMenuCheckStrictly()) {
+            parentIds = baseMapper.selectObjs(new LambdaQueryWrapper<SysMenu>()
+                .select(SysMenu::getParentId)
+                .in(SysMenu::getMenuId, menuIds), Convert::toLong);
+        }
+        return baseMapper.selectObjs(new LambdaQueryWrapper<SysMenu>()
+            .in(SysMenu::getMenuId, menuIds)
+            .notIn(CollUtil.isNotEmpty(parentIds), SysMenu::getMenuId, parentIds), Convert::toLong);
+    }
+
+    /**
+     * 鏋勫缓鍓嶇璺敱鎵�闇�瑕佺殑鑿滃崟
+     *
+     * @param menus 鑿滃崟鍒楄〃
+     * @return 璺敱鍒楄〃
+     */
+    @Override
+    public List<RouterVo> buildMenus(List<SysMenu> menus) {
+        List<RouterVo> routers = new LinkedList<>();
+        for (SysMenu menu : menus) {
+            RouterVo router = new RouterVo();
+            router.setHidden("1".equals(menu.getVisible()));
+            router.setName(menu.getRouteName());
+            router.setPath(menu.getRouterPath());
+            router.setComponent(menu.getComponentInfo());
+            router.setQuery(menu.getQueryParam());
+            router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath()));
+            List<SysMenu> cMenus = menu.getChildren();
+            if (CollUtil.isNotEmpty(cMenus) && UserConstants.TYPE_DIR.equals(menu.getMenuType())) {
+                router.setAlwaysShow(true);
+                router.setRedirect("noRedirect");
+                router.setChildren(buildMenus(cMenus));
+            } else if (menu.isMenuFrame()) {
+                router.setMeta(null);
+                List<RouterVo> childrenList = new ArrayList<>();
+                RouterVo children = new RouterVo();
+                children.setPath(menu.getPath());
+                children.setComponent(menu.getComponentInfo());
+                children.setName(StringUtils.capitalize(menu.getPath()));
+                children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath()));
+                children.setQuery(menu.getQueryParam());
+                childrenList.add(children);
+                router.setChildren(childrenList);
+            } else if (menu.getParentId().intValue() == 0 && menu.isInnerLink()) {
+                router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon()));
+                router.setPath("/");
+                List<RouterVo> childrenList = new ArrayList<>();
+                RouterVo children = new RouterVo();
+                String routerPath = SysMenu.innerLinkReplaceEach(menu.getPath());
+                children.setPath(routerPath);
+                children.setComponent(UserConstants.INNER_LINK);
+                children.setName(StringUtils.capitalize(routerPath));
+                children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath()));
+                childrenList.add(children);
+                router.setChildren(childrenList);
+            }
+            routers.add(router);
+        }
+        return routers;
+    }
+
+    /**
+     * 鏋勫缓鍓嶇鎵�闇�瑕佷笅鎷夋爲缁撴瀯
+     *
+     * @param menus 鑿滃崟鍒楄〃
+     * @return 涓嬫媺鏍戠粨鏋勫垪琛�
+     */
+    @Override
+    public List<Tree<Long>> buildMenuTreeSelect(List<SysMenuVo> menus) {
+        if (CollUtil.isEmpty(menus)) {
+            return CollUtil.newArrayList();
+        }
+        return TreeBuildUtils.build(menus, (menu, tree) ->
+            tree.setId(menu.getMenuId())
+                .setParentId(menu.getParentId())
+                .setName(menu.getMenuName())
+                .setWeight(menu.getOrderNum()));
+    }
+
+    /**
+     * 鏍规嵁鑿滃崟ID鏌ヨ淇℃伅
+     *
+     * @param menuId 鑿滃崟ID
+     * @return 鑿滃崟淇℃伅
+     */
+    @Override
+    public SysMenuVo selectMenuById(Long menuId) {
+        return baseMapper.selectVoById(menuId);
+    }
+
+    /**
+     * 鏄惁瀛樺湪鑿滃崟瀛愯妭鐐�
+     *
+     * @param menuId 鑿滃崟ID
+     * @return 缁撴灉
+     */
+    @Override
+    public boolean hasChildByMenuId(Long menuId) {
+        return baseMapper.exists(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getParentId, menuId));
+    }
+
+    /**
+     * 鏌ヨ鑿滃崟浣跨敤鏁伴噺
+     *
+     * @param menuId 鑿滃崟ID
+     * @return 缁撴灉
+     */
+    @Override
+    public boolean checkMenuExistRole(Long menuId) {
+        return roleMenuMapper.exists(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getMenuId, menuId));
+    }
+
+    /**
+     * 鏂板淇濆瓨鑿滃崟淇℃伅
+     *
+     * @param bo 鑿滃崟淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    public int insertMenu(SysMenuBo bo) {
+        SysMenu menu = MapstructUtils.convert(bo, SysMenu.class);
+        return baseMapper.insert(menu);
+    }
+
+    /**
+     * 淇敼淇濆瓨鑿滃崟淇℃伅
+     *
+     * @param bo 鑿滃崟淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    public int updateMenu(SysMenuBo bo) {
+        SysMenu menu = MapstructUtils.convert(bo, SysMenu.class);
+        return baseMapper.updateById(menu);
+    }
+
+    /**
+     * 鍒犻櫎鑿滃崟绠$悊淇℃伅
+     *
+     * @param menuId 鑿滃崟ID
+     * @return 缁撴灉
+     */
+    @Override
+    public int deleteMenuById(Long menuId) {
+        return baseMapper.deleteById(menuId);
+    }
+
+    /**
+     * 鏍¢獙鑿滃崟鍚嶇О鏄惁鍞竴
+     *
+     * @param menu 鑿滃崟淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    public boolean checkMenuNameUnique(SysMenuBo menu) {
+        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysMenu>()
+            .eq(SysMenu::getMenuName, menu.getMenuName())
+            .eq(SysMenu::getParentId, menu.getParentId())
+            .ne(ObjectUtil.isNotNull(menu.getMenuId()), SysMenu::getMenuId, menu.getMenuId()));
+        return !exist;
+    }
+
+    /**
+     * 鏍规嵁鐖惰妭鐐圭殑ID鑾峰彇鎵�鏈夊瓙鑺傜偣
+     *
+     * @param list     鍒嗙被琛�
+     * @param parentId 浼犲叆鐨勭埗鑺傜偣ID
+     * @return String
+     */
+    private List<SysMenu> getChildPerms(List<SysMenu> list, int parentId) {
+        List<SysMenu> returnList = new ArrayList<>();
+        for (SysMenu t : list) {
+            // 涓�銆佹牴鎹紶鍏ョ殑鏌愪釜鐖惰妭鐐笽D,閬嶅巻璇ョ埗鑺傜偣鐨勬墍鏈夊瓙鑺傜偣
+            if (t.getParentId() == parentId) {
+                recursionFn(list, t);
+                returnList.add(t);
+            }
+        }
+        return returnList;
+    }
+
+    /**
+     * 閫掑綊鍒楄〃
+     */
+    private void recursionFn(List<SysMenu> list, SysMenu t) {
+        // 寰楀埌瀛愯妭鐐瑰垪琛�
+        List<SysMenu> childList = StreamUtils.filter(list, n -> n.getParentId().equals(t.getMenuId()));
+        t.setChildren(childList);
+        for (SysMenu tChild : childList) {
+            // 鍒ゆ柇鏄惁鏈夊瓙鑺傜偣
+            if (list.stream().anyMatch(n -> n.getParentId().equals(tChild.getMenuId()))) {
+                recursionFn(list, tChild);
+            }
+        }
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysNoticeServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysNoticeServiceImpl.java
new file mode 100644
index 0000000..c0b2cef
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysNoticeServiceImpl.java
@@ -0,0 +1,122 @@
+package org.dromara.system.service.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.system.domain.SysNotice;
+import org.dromara.system.domain.bo.SysNoticeBo;
+import org.dromara.system.domain.vo.SysNoticeVo;
+import org.dromara.system.domain.vo.SysUserVo;
+import org.dromara.system.mapper.SysNoticeMapper;
+import org.dromara.system.mapper.SysUserMapper;
+import org.dromara.system.service.ISysNoticeService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 鍏憡 鏈嶅姟灞傚疄鐜�
+ *
+ * @author Lion Li
+ */
+@RequiredArgsConstructor
+@Service
+public class SysNoticeServiceImpl implements ISysNoticeService {
+
+    private final SysNoticeMapper baseMapper;
+    private final SysUserMapper userMapper;
+
+    @Override
+    public TableDataInfo<SysNoticeVo> selectPageNoticeList(SysNoticeBo notice, PageQuery pageQuery) {
+        LambdaQueryWrapper<SysNotice> lqw = buildQueryWrapper(notice);
+        Page<SysNoticeVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(page);
+    }
+
+    /**
+     * 鏌ヨ鍏憡淇℃伅
+     *
+     * @param noticeId 鍏憡ID
+     * @return 鍏憡淇℃伅
+     */
+    @Override
+    public SysNoticeVo selectNoticeById(Long noticeId) {
+        return baseMapper.selectVoById(noticeId);
+    }
+
+    /**
+     * 鏌ヨ鍏憡鍒楄〃
+     *
+     * @param notice 鍏憡淇℃伅
+     * @return 鍏憡闆嗗悎
+     */
+    @Override
+    public List<SysNoticeVo> selectNoticeList(SysNoticeBo notice) {
+        LambdaQueryWrapper<SysNotice> lqw = buildQueryWrapper(notice);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<SysNotice> buildQueryWrapper(SysNoticeBo bo) {
+        LambdaQueryWrapper<SysNotice> lqw = Wrappers.lambdaQuery();
+        lqw.like(StringUtils.isNotBlank(bo.getNoticeTitle()), SysNotice::getNoticeTitle, bo.getNoticeTitle());
+        lqw.eq(StringUtils.isNotBlank(bo.getNoticeType()), SysNotice::getNoticeType, bo.getNoticeType());
+        if (StringUtils.isNotBlank(bo.getCreateByName())) {
+            SysUserVo sysUser = userMapper.selectUserByUserName(bo.getCreateByName());
+            lqw.eq(SysNotice::getCreateBy, ObjectUtil.isNotNull(sysUser) ? sysUser.getUserId() : null);
+        }
+        return lqw;
+    }
+
+    /**
+     * 鏂板鍏憡
+     *
+     * @param bo 鍏憡淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    public int insertNotice(SysNoticeBo bo) {
+        SysNotice notice = MapstructUtils.convert(bo, SysNotice.class);
+        return baseMapper.insert(notice);
+    }
+
+    /**
+     * 淇敼鍏憡
+     *
+     * @param bo 鍏憡淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    public int updateNotice(SysNoticeBo bo) {
+        SysNotice notice = MapstructUtils.convert(bo, SysNotice.class);
+        return baseMapper.updateById(notice);
+    }
+
+    /**
+     * 鍒犻櫎鍏憡瀵硅薄
+     *
+     * @param noticeId 鍏憡ID
+     * @return 缁撴灉
+     */
+    @Override
+    public int deleteNoticeById(Long noticeId) {
+        return baseMapper.deleteById(noticeId);
+    }
+
+    /**
+     * 鎵归噺鍒犻櫎鍏憡淇℃伅
+     *
+     * @param noticeIds 闇�瑕佸垹闄ょ殑鍏憡ID
+     * @return 缁撴灉
+     */
+    @Override
+    public int deleteNoticeByIds(Long[] noticeIds) {
+        return baseMapper.deleteBatchIds(Arrays.asList(noticeIds));
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOperLogServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOperLogServiceImpl.java
new file mode 100644
index 0000000..40e7fd3
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOperLogServiceImpl.java
@@ -0,0 +1,144 @@
+package org.dromara.system.service.impl;
+
+import cn.hutool.core.util.ArrayUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.core.utils.ip.AddressUtils;
+import org.dromara.common.log.event.OperLogEvent;
+import org.dromara.system.domain.SysOperLog;
+import org.dromara.system.domain.bo.SysOperLogBo;
+import org.dromara.system.domain.vo.SysOperLogVo;
+import org.dromara.system.mapper.SysOperLogMapper;
+import org.dromara.system.service.ISysOperLogService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 鎿嶄綔鏃ュ織 鏈嶅姟灞傚鐞�
+ *
+ * @author Lion Li
+ */
+@RequiredArgsConstructor
+@Service
+public class SysOperLogServiceImpl implements ISysOperLogService {
+
+    private final SysOperLogMapper baseMapper;
+
+    /**
+     * 鎿嶄綔鏃ュ織璁板綍
+     *
+     * @param operLogEvent 鎿嶄綔鏃ュ織浜嬩欢
+     */
+    @Async
+    @EventListener
+    public void recordOper(OperLogEvent operLogEvent) {
+        SysOperLogBo operLog = MapstructUtils.convert(operLogEvent, SysOperLogBo.class);
+        // 杩滅▼鏌ヨ鎿嶄綔鍦扮偣
+        operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
+        insertOperlog(operLog);
+    }
+
+    @Override
+    public TableDataInfo<SysOperLogVo> selectPageOperLogList(SysOperLogBo operLog, PageQuery pageQuery) {
+        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())
+            .between(params.get("beginTime") != null && params.get("endTime") != null,
+                SysOperLog::getOperTime, params.get("beginTime"), params.get("endTime"));
+        if (StringUtils.isBlank(pageQuery.getOrderByColumn())) {
+            pageQuery.setOrderByColumn("oper_id");
+            pageQuery.setIsAsc("desc");
+        }
+        Page<SysOperLogVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(page);
+    }
+
+    /**
+     * 鏂板鎿嶄綔鏃ュ織
+     *
+     * @param bo 鎿嶄綔鏃ュ織瀵硅薄
+     */
+    @Override
+    public void insertOperlog(SysOperLogBo bo) {
+        SysOperLog operLog = MapstructUtils.convert(bo, SysOperLog.class);
+        operLog.setOperTime(new Date());
+        baseMapper.insert(operLog);
+    }
+
+    /**
+     * 鏌ヨ绯荤粺鎿嶄綔鏃ュ織闆嗗悎
+     *
+     * @param operLog 鎿嶄綔鏃ュ織瀵硅薄
+     * @return 鎿嶄綔鏃ュ織闆嗗悎
+     */
+    @Override
+    public List<SysOperLogVo> selectOperLogList(SysOperLogBo operLog) {
+        Map<String, Object> params = operLog.getParams();
+        return baseMapper.selectVoList(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())
+            .between(params.get("beginTime") != null && params.get("endTime") != null,
+                SysOperLog::getOperTime, params.get("beginTime"), params.get("endTime"))
+            .orderByDesc(SysOperLog::getOperId));
+    }
+
+    /**
+     * 鎵归噺鍒犻櫎绯荤粺鎿嶄綔鏃ュ織
+     *
+     * @param operIds 闇�瑕佸垹闄ょ殑鎿嶄綔鏃ュ織ID
+     * @return 缁撴灉
+     */
+    @Override
+    public int deleteOperLogByIds(Long[] operIds) {
+        return baseMapper.deleteBatchIds(Arrays.asList(operIds));
+    }
+
+    /**
+     * 鏌ヨ鎿嶄綔鏃ュ織璇︾粏
+     *
+     * @param operId 鎿嶄綔ID
+     * @return 鎿嶄綔鏃ュ織瀵硅薄
+     */
+    @Override
+    public SysOperLogVo selectOperLogById(Long operId) {
+        return baseMapper.selectVoById(operId);
+    }
+
+    /**
+     * 娓呯┖鎿嶄綔鏃ュ織
+     */
+    @Override
+    public void cleanOperLog() {
+        baseMapper.delete(new LambdaQueryWrapper<>());
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssConfigServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssConfigServiceImpl.java
new file mode 100644
index 0000000..2c4d1ea
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssConfigServiceImpl.java
@@ -0,0 +1,183 @@
+package org.dromara.system.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.dromara.common.core.constant.CacheNames;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StreamUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.json.utils.JsonUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.oss.constant.OssConstant;
+import org.dromara.common.redis.utils.CacheUtils;
+import org.dromara.common.redis.utils.RedisUtils;
+import org.dromara.common.tenant.core.TenantEntity;
+import org.dromara.common.tenant.helper.TenantHelper;
+import org.dromara.system.domain.SysOssConfig;
+import org.dromara.system.domain.bo.SysOssConfigBo;
+import org.dromara.system.domain.vo.SysOssConfigVo;
+import org.dromara.system.mapper.SysOssConfigMapper;
+import org.dromara.system.service.ISysOssConfigService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 瀵硅薄瀛樺偍閰嶇疆Service涓氬姟灞傚鐞�
+ *
+ * @author Lion Li
+ * @author 瀛よ垷鐑熼洦
+ * @date 2021-08-13
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class SysOssConfigServiceImpl implements ISysOssConfigService {
+
+    private final SysOssConfigMapper baseMapper;
+
+    /**
+     * 椤圭洰鍚姩鏃讹紝鍒濆鍖栧弬鏁板埌缂撳瓨锛屽姞杞介厤缃被
+     */
+    @Override
+    public void init() {
+        TenantHelper.enableIgnore();
+        List<SysOssConfig> list = baseMapper.selectList(
+                new LambdaQueryWrapper<SysOssConfig>().orderByAsc(TenantEntity::getTenantId));
+        TenantHelper.disableIgnore();
+        Map<String, List<SysOssConfig>> map = StreamUtils.groupByKey(list, SysOssConfig::getTenantId);
+        for (String tenantId : map.keySet()) {
+            TenantHelper.setDynamic(tenantId);
+            // 鍔犺浇OSS鍒濆鍖栭厤缃�
+            for (SysOssConfig config : map.get(tenantId)) {
+                String configKey = config.getConfigKey();
+                if ("0".equals(config.getStatus())) {
+                    RedisUtils.setCacheObject(OssConstant.DEFAULT_CONFIG_KEY, configKey);
+                }
+                CacheUtils.put(CacheNames.SYS_OSS_CONFIG, config.getConfigKey(), JsonUtils.toJsonString(config));
+            }
+        }
+        TenantHelper.clearDynamic();
+    }
+
+    @Override
+    public SysOssConfigVo queryById(Long ossConfigId) {
+        return baseMapper.selectVoById(ossConfigId);
+    }
+
+    @Override
+    public TableDataInfo<SysOssConfigVo> queryPageList(SysOssConfigBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<SysOssConfig> lqw = buildQueryWrapper(bo);
+        Page<SysOssConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+
+    private LambdaQueryWrapper<SysOssConfig> buildQueryWrapper(SysOssConfigBo bo) {
+        LambdaQueryWrapper<SysOssConfig> lqw = Wrappers.lambdaQuery();
+        lqw.eq(StringUtils.isNotBlank(bo.getConfigKey()), SysOssConfig::getConfigKey, bo.getConfigKey());
+        lqw.like(StringUtils.isNotBlank(bo.getBucketName()), SysOssConfig::getBucketName, bo.getBucketName());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysOssConfig::getStatus, bo.getStatus());
+        return lqw;
+    }
+
+    @Override
+    public Boolean insertByBo(SysOssConfigBo bo) {
+        SysOssConfig config = MapstructUtils.convert(bo, SysOssConfig.class);
+        validEntityBeforeSave(config);
+        boolean flag = baseMapper.insert(config) > 0;
+        if (flag) {
+            CacheUtils.put(CacheNames.SYS_OSS_CONFIG, config.getConfigKey(), JsonUtils.toJsonString(config));
+        }
+        return flag;
+    }
+
+    @Override
+    public Boolean updateByBo(SysOssConfigBo bo) {
+        SysOssConfig config = MapstructUtils.convert(bo, SysOssConfig.class);
+        validEntityBeforeSave(config);
+        LambdaUpdateWrapper<SysOssConfig> luw = new LambdaUpdateWrapper<>();
+        luw.set(ObjectUtil.isNull(config.getPrefix()), SysOssConfig::getPrefix, "");
+        luw.set(ObjectUtil.isNull(config.getRegion()), SysOssConfig::getRegion, "");
+        luw.set(ObjectUtil.isNull(config.getExt1()), SysOssConfig::getExt1, "");
+        luw.set(ObjectUtil.isNull(config.getRemark()), SysOssConfig::getRemark, "");
+        luw.eq(SysOssConfig::getOssConfigId, config.getOssConfigId());
+        boolean flag = baseMapper.update(config, luw) > 0;
+        if (flag) {
+            CacheUtils.put(CacheNames.SYS_OSS_CONFIG, config.getConfigKey(), JsonUtils.toJsonString(config));
+        }
+        return flag;
+    }
+
+    /**
+     * 淇濆瓨鍓嶇殑鏁版嵁鏍¢獙
+     */
+    private void validEntityBeforeSave(SysOssConfig entity) {
+        if (StringUtils.isNotEmpty(entity.getConfigKey())
+            && !checkConfigKeyUnique(entity)) {
+            throw new ServiceException("鎿嶄綔閰嶇疆'" + entity.getConfigKey() + "'澶辫触, 閰嶇疆key宸插瓨鍦�!");
+        }
+    }
+
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            if (CollUtil.containsAny(ids, OssConstant.SYSTEM_DATA_IDS)) {
+                throw new ServiceException("绯荤粺鍐呯疆, 涓嶅彲鍒犻櫎!");
+            }
+        }
+        List<SysOssConfig> list = CollUtil.newArrayList();
+        for (Long configId : ids) {
+            SysOssConfig config = baseMapper.selectById(configId);
+            list.add(config);
+        }
+        boolean flag = baseMapper.deleteBatchIds(ids) > 0;
+        if (flag) {
+            list.forEach(sysOssConfig ->
+                CacheUtils.evict(CacheNames.SYS_OSS_CONFIG, sysOssConfig.getConfigKey()));
+        }
+        return flag;
+    }
+
+    /**
+     * 鍒ゆ柇configKey鏄惁鍞竴
+     */
+    private boolean checkConfigKeyUnique(SysOssConfig sysOssConfig) {
+        long ossConfigId = ObjectUtil.isNull(sysOssConfig.getOssConfigId()) ? -1L : sysOssConfig.getOssConfigId();
+        SysOssConfig info = baseMapper.selectOne(new LambdaQueryWrapper<SysOssConfig>()
+            .select(SysOssConfig::getOssConfigId, SysOssConfig::getConfigKey)
+            .eq(SysOssConfig::getConfigKey, sysOssConfig.getConfigKey()));
+        if (ObjectUtil.isNotNull(info) && info.getOssConfigId() != ossConfigId) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 鍚敤绂佺敤鐘舵��
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int updateOssConfigStatus(SysOssConfigBo bo) {
+        SysOssConfig sysOssConfig = MapstructUtils.convert(bo, SysOssConfig.class);
+        int row = baseMapper.update(null, new LambdaUpdateWrapper<SysOssConfig>()
+            .set(SysOssConfig::getStatus, "1"));
+        row += baseMapper.updateById(sysOssConfig);
+        if (row > 0) {
+            RedisUtils.setCacheObject(OssConstant.DEFAULT_CONFIG_KEY, sysOssConfig.getConfigKey());
+        }
+        return row;
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssServiceImpl.java
new file mode 100644
index 0000000..3923c63
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssServiceImpl.java
@@ -0,0 +1,171 @@
+package org.dromara.system.service.impl;
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.dromara.common.core.constant.CacheNames;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.service.OssService;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.StreamUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.core.utils.file.FileUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.oss.core.OssClient;
+import org.dromara.common.oss.entity.UploadResult;
+import org.dromara.common.oss.enumd.AccessPolicyType;
+import org.dromara.common.oss.factory.OssFactory;
+import org.dromara.system.domain.SysOss;
+import org.dromara.system.domain.bo.SysOssBo;
+import org.dromara.system.domain.vo.SysOssVo;
+import org.dromara.system.mapper.SysOssMapper;
+import org.dromara.system.service.ISysOssService;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.*;
+
+/**
+ * 鏂囦欢涓婁紶 鏈嶅姟灞傚疄鐜�
+ *
+ * @author Lion Li
+ */
+@RequiredArgsConstructor
+@Service
+public class SysOssServiceImpl implements ISysOssService, OssService {
+
+    private final SysOssMapper baseMapper;
+
+    @Override
+    public TableDataInfo<SysOssVo> queryPageList(SysOssBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<SysOss> lqw = buildQueryWrapper(bo);
+        Page<SysOssVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        List<SysOssVo> filterResult = StreamUtils.toList(result.getRecords(), this::matchingUrl);
+        result.setRecords(filterResult);
+        return TableDataInfo.build(result);
+    }
+
+    @Override
+    public List<SysOssVo> listByIds(Collection<Long> ossIds) {
+        List<SysOssVo> list = new ArrayList<>();
+        for (Long id : ossIds) {
+            SysOssVo vo = SpringUtils.getAopProxy(this).getById(id);
+            if (ObjectUtil.isNotNull(vo)) {
+                list.add(this.matchingUrl(vo));
+            }
+        }
+        return list;
+    }
+
+    @Override
+    public String selectUrlByIds(String ossIds) {
+        List<String> list = new ArrayList<>();
+        for (Long id : StringUtils.splitTo(ossIds, Convert::toLong)) {
+            SysOssVo vo = SpringUtils.getAopProxy(this).getById(id);
+            if (ObjectUtil.isNotNull(vo)) {
+                list.add(this.matchingUrl(vo).getUrl());
+            }
+        }
+        return String.join(StringUtils.SEPARATOR, list);
+    }
+
+    private LambdaQueryWrapper<SysOss> buildQueryWrapper(SysOssBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<SysOss> lqw = Wrappers.lambdaQuery();
+        lqw.like(StringUtils.isNotBlank(bo.getFileName()), SysOss::getFileName, bo.getFileName());
+        lqw.like(StringUtils.isNotBlank(bo.getOriginalName()), SysOss::getOriginalName, bo.getOriginalName());
+        lqw.eq(StringUtils.isNotBlank(bo.getFileSuffix()), SysOss::getFileSuffix, bo.getFileSuffix());
+        lqw.eq(StringUtils.isNotBlank(bo.getUrl()), SysOss::getUrl, bo.getUrl());
+        lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
+            SysOss::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime"));
+        lqw.eq(ObjectUtil.isNotNull(bo.getCreateBy()), SysOss::getCreateBy, bo.getCreateBy());
+        lqw.eq(StringUtils.isNotBlank(bo.getService()), SysOss::getService, bo.getService());
+        return lqw;
+    }
+
+    @Cacheable(cacheNames = CacheNames.SYS_OSS, key = "#ossId")
+    @Override
+    public SysOssVo getById(Long ossId) {
+        return baseMapper.selectVoById(ossId);
+    }
+
+    @Override
+    public void download(Long ossId, HttpServletResponse response) throws IOException {
+        SysOssVo sysOss = SpringUtils.getAopProxy(this).getById(ossId);
+        if (ObjectUtil.isNull(sysOss)) {
+            throw new ServiceException("鏂囦欢鏁版嵁涓嶅瓨鍦�!");
+        }
+        FileUtils.setAttachmentResponseHeader(response, sysOss.getOriginalName());
+        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8");
+        OssClient storage = OssFactory.instance();
+        try(InputStream inputStream = storage.getObjectContent(sysOss.getUrl())) {
+            int available = inputStream.available();
+            IoUtil.copy(inputStream, response.getOutputStream(), available);
+            response.setContentLength(available);
+        } catch (Exception e) {
+            throw new ServiceException(e.getMessage());
+        }
+    }
+
+    @Override
+    public SysOssVo upload(MultipartFile file) {
+        String originalfileName = file.getOriginalFilename();
+        String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length());
+        OssClient storage = OssFactory.instance();
+        UploadResult uploadResult;
+        try {
+            uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType());
+        } catch (IOException e) {
+            throw new ServiceException(e.getMessage());
+        }
+        // 淇濆瓨鏂囦欢淇℃伅
+        SysOss oss = new SysOss();
+        oss.setUrl(uploadResult.getUrl());
+        oss.setFileSuffix(suffix);
+        oss.setFileName(uploadResult.getFilename());
+        oss.setOriginalName(originalfileName);
+        oss.setService(storage.getConfigKey());
+        baseMapper.insert(oss);
+        SysOssVo sysOssVo = MapstructUtils.convert(oss, SysOssVo.class);
+        return this.matchingUrl(sysOssVo);
+    }
+
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            // 鍋氫竴浜涗笟鍔′笂鐨勬牎楠�,鍒ゆ柇鏄惁闇�瑕佹牎楠�
+        }
+        List<SysOss> list = baseMapper.selectBatchIds(ids);
+        for (SysOss sysOss : list) {
+            OssClient storage = OssFactory.instance(sysOss.getService());
+            storage.delete(sysOss.getUrl());
+        }
+        return baseMapper.deleteBatchIds(ids) > 0;
+    }
+
+    /**
+     * 鍖归厤Url
+     *
+     * @param oss OSS瀵硅薄
+     * @return oss 鍖归厤Url鐨凮SS瀵硅薄
+     */
+    private SysOssVo matchingUrl(SysOssVo oss) {
+        OssClient storage = OssFactory.instance(oss.getService());
+        // 浠呬慨鏀规《绫诲瀷涓� private 鐨刄RL锛屼复鏃禪RL鏃堕暱涓�120s
+        if (AccessPolicyType.PRIVATE == storage.getAccessPolicy()) {
+            oss.setUrl(storage.getPrivateUrl(oss.getFileName(), 120));
+        }
+        return oss;
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPermissionServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPermissionServiceImpl.java
new file mode 100644
index 0000000..9852821
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPermissionServiceImpl.java
@@ -0,0 +1,61 @@
+package org.dromara.system.service.impl;
+
+import org.dromara.common.core.constant.TenantConstants;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.system.service.ISysMenuService;
+import org.dromara.system.service.ISysPermissionService;
+import org.dromara.system.service.ISysRoleService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * 鐢ㄦ埛鏉冮檺澶勭悊
+ *
+ * @author ruoyi
+ */
+@RequiredArgsConstructor
+@Service
+public class SysPermissionServiceImpl implements ISysPermissionService {
+
+    private final ISysRoleService roleService;
+    private final ISysMenuService menuService;
+
+    /**
+     * 鑾峰彇瑙掕壊鏁版嵁鏉冮檺
+     *
+     * @param userId  鐢ㄦ埛id
+     * @return 瑙掕壊鏉冮檺淇℃伅
+     */
+    @Override
+    public Set<String> getRolePermission(Long userId) {
+        Set<String> roles = new HashSet<>();
+        // 绠$悊鍛樻嫢鏈夋墍鏈夋潈闄�
+        if (LoginHelper.isSuperAdmin(userId)) {
+            roles.add(TenantConstants.SUPER_ADMIN_ROLE_KEY);
+        } else {
+            roles.addAll(roleService.selectRolePermissionByUserId(userId));
+        }
+        return roles;
+    }
+
+    /**
+     * 鑾峰彇鑿滃崟鏁版嵁鏉冮檺
+     *
+     * @param userId  鐢ㄦ埛id
+     * @return 鑿滃崟鏉冮檺淇℃伅
+     */
+    @Override
+    public Set<String> getMenuPermission(Long userId) {
+        Set<String> perms = new HashSet<>();
+        // 绠$悊鍛樻嫢鏈夋墍鏈夋潈闄�
+        if (LoginHelper.isSuperAdmin(userId)) {
+            perms.add("*:*:*");
+        } else {
+            perms.addAll(menuService.selectMenuPermsByUserId(userId));
+        }
+        return perms;
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPostServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPostServiceImpl.java
new file mode 100644
index 0000000..d9529e7
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPostServiceImpl.java
@@ -0,0 +1,188 @@
+package org.dromara.system.service.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.system.domain.SysPost;
+import org.dromara.system.domain.SysUserPost;
+import org.dromara.system.domain.bo.SysPostBo;
+import org.dromara.system.domain.vo.SysPostVo;
+import org.dromara.system.mapper.SysPostMapper;
+import org.dromara.system.mapper.SysUserPostMapper;
+import org.dromara.system.service.ISysPostService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 宀椾綅淇℃伅 鏈嶅姟灞傚鐞�
+ *
+ * @author Lion Li
+ */
+@RequiredArgsConstructor
+@Service
+public class SysPostServiceImpl implements ISysPostService {
+
+    private final SysPostMapper baseMapper;
+    private final SysUserPostMapper userPostMapper;
+
+    @Override
+    public TableDataInfo<SysPostVo> selectPagePostList(SysPostBo post, PageQuery pageQuery) {
+        LambdaQueryWrapper<SysPost> lqw = buildQueryWrapper(post);
+        Page<SysPostVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(page);
+    }
+
+    /**
+     * 鏌ヨ宀椾綅淇℃伅闆嗗悎
+     *
+     * @param post 宀椾綅淇℃伅
+     * @return 宀椾綅淇℃伅闆嗗悎
+     */
+    @Override
+    public List<SysPostVo> selectPostList(SysPostBo post) {
+        LambdaQueryWrapper<SysPost> lqw = buildQueryWrapper(post);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<SysPost> buildQueryWrapper(SysPostBo bo) {
+        LambdaQueryWrapper<SysPost> lqw = Wrappers.lambdaQuery();
+        lqw.like(StringUtils.isNotBlank(bo.getPostCode()), SysPost::getPostCode, bo.getPostCode());
+        lqw.like(StringUtils.isNotBlank(bo.getPostName()), SysPost::getPostName, bo.getPostName());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysPost::getStatus, bo.getStatus());
+        lqw.orderByAsc(SysPost::getPostSort);
+        return lqw;
+    }
+
+    /**
+     * 鏌ヨ鎵�鏈夊矖浣�
+     *
+     * @return 宀椾綅鍒楄〃
+     */
+    @Override
+    public List<SysPostVo> selectPostAll() {
+        return baseMapper.selectVoList(new QueryWrapper<>());
+    }
+
+    /**
+     * 閫氳繃宀椾綅ID鏌ヨ宀椾綅淇℃伅
+     *
+     * @param postId 宀椾綅ID
+     * @return 瑙掕壊瀵硅薄淇℃伅
+     */
+    @Override
+    public SysPostVo selectPostById(Long postId) {
+        return baseMapper.selectVoById(postId);
+    }
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鑾峰彇宀椾綅閫夋嫨妗嗗垪琛�
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 閫変腑宀椾綅ID鍒楄〃
+     */
+    @Override
+    public List<Long> selectPostListByUserId(Long userId) {
+        return baseMapper.selectPostListByUserId(userId);
+    }
+
+    /**
+     * 鏍¢獙宀椾綅鍚嶇О鏄惁鍞竴
+     *
+     * @param post 宀椾綅淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    public boolean checkPostNameUnique(SysPostBo post) {
+        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysPost>()
+            .eq(SysPost::getPostName, post.getPostName())
+            .ne(ObjectUtil.isNotNull(post.getPostId()), SysPost::getPostId, post.getPostId()));
+        return !exist;
+    }
+
+    /**
+     * 鏍¢獙宀椾綅缂栫爜鏄惁鍞竴
+     *
+     * @param post 宀椾綅淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    public boolean checkPostCodeUnique(SysPostBo post) {
+        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysPost>()
+            .eq(SysPost::getPostCode, post.getPostCode())
+            .ne(ObjectUtil.isNotNull(post.getPostId()), SysPost::getPostId, post.getPostId()));
+        return !exist;
+    }
+
+    /**
+     * 閫氳繃宀椾綅ID鏌ヨ宀椾綅浣跨敤鏁伴噺
+     *
+     * @param postId 宀椾綅ID
+     * @return 缁撴灉
+     */
+    @Override
+    public long countUserPostById(Long postId) {
+        return userPostMapper.selectCount(new LambdaQueryWrapper<SysUserPost>().eq(SysUserPost::getPostId, postId));
+    }
+
+    /**
+     * 鍒犻櫎宀椾綅淇℃伅
+     *
+     * @param postId 宀椾綅ID
+     * @return 缁撴灉
+     */
+    @Override
+    public int deletePostById(Long postId) {
+        return baseMapper.deleteById(postId);
+    }
+
+    /**
+     * 鎵归噺鍒犻櫎宀椾綅淇℃伅
+     *
+     * @param postIds 闇�瑕佸垹闄ょ殑宀椾綅ID
+     * @return 缁撴灉
+     */
+    @Override
+    public int deletePostByIds(Long[] postIds) {
+        for (Long postId : postIds) {
+            SysPost post = baseMapper.selectById(postId);
+            if (countUserPostById(postId) > 0) {
+                throw new ServiceException(String.format("%1$s宸插垎閰�,涓嶈兘鍒犻櫎", post.getPostName()));
+            }
+        }
+        return baseMapper.deleteBatchIds(Arrays.asList(postIds));
+    }
+
+    /**
+     * 鏂板淇濆瓨宀椾綅淇℃伅
+     *
+     * @param bo 宀椾綅淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    public int insertPost(SysPostBo bo) {
+        SysPost post = MapstructUtils.convert(bo, SysPost.class);
+        return baseMapper.insert(post);
+    }
+
+    /**
+     * 淇敼淇濆瓨宀椾綅淇℃伅
+     *
+     * @param bo 宀椾綅淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    public int updatePost(SysPostBo bo) {
+        SysPost post = MapstructUtils.convert(bo, SysPost.class);
+        return baseMapper.updateById(post);
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java
new file mode 100644
index 0000000..47527da
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java
@@ -0,0 +1,421 @@
+package org.dromara.system.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.dromara.common.core.constant.UserConstants;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StreamUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.system.domain.SysRole;
+import org.dromara.system.domain.SysRoleDept;
+import org.dromara.system.domain.SysRoleMenu;
+import org.dromara.system.domain.SysUserRole;
+import org.dromara.system.domain.bo.SysRoleBo;
+import org.dromara.system.domain.vo.SysRoleVo;
+import org.dromara.system.mapper.SysRoleDeptMapper;
+import org.dromara.system.mapper.SysRoleMapper;
+import org.dromara.system.mapper.SysRoleMenuMapper;
+import org.dromara.system.mapper.SysUserRoleMapper;
+import org.dromara.system.service.ISysRoleService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+
+/**
+ * 瑙掕壊 涓氬姟灞傚鐞�
+ *
+ * @author Lion Li
+ */
+@RequiredArgsConstructor
+@Service
+public class SysRoleServiceImpl implements ISysRoleService {
+
+    private final SysRoleMapper baseMapper;
+    private final SysRoleMenuMapper roleMenuMapper;
+    private final SysUserRoleMapper userRoleMapper;
+    private final SysRoleDeptMapper roleDeptMapper;
+
+    @Override
+    public TableDataInfo<SysRoleVo> selectPageRoleList(SysRoleBo role, PageQuery pageQuery) {
+        Page<SysRoleVo> page = baseMapper.selectPageRoleList(pageQuery.build(), this.buildQueryWrapper(role));
+        return TableDataInfo.build(page);
+    }
+
+    /**
+     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瑙掕壊鏁版嵁
+     *
+     * @param role 瑙掕壊淇℃伅
+     * @return 瑙掕壊鏁版嵁闆嗗悎淇℃伅
+     */
+    @Override
+    public List<SysRoleVo> selectRoleList(SysRoleBo role) {
+        return baseMapper.selectRoleList(this.buildQueryWrapper(role));
+    }
+
+    private Wrapper<SysRole> buildQueryWrapper(SysRoleBo bo) {
+        Map<String, Object> params = bo.getParams();
+        QueryWrapper<SysRole> wrapper = Wrappers.query();
+        wrapper.eq("r.del_flag", UserConstants.ROLE_NORMAL)
+            .eq(ObjectUtil.isNotNull(bo.getRoleId()), "r.role_id", bo.getRoleId())
+            .like(StringUtils.isNotBlank(bo.getRoleName()), "r.role_name", bo.getRoleName())
+            .eq(StringUtils.isNotBlank(bo.getStatus()), "r.status", bo.getStatus())
+            .like(StringUtils.isNotBlank(bo.getRoleKey()), "r.role_key", bo.getRoleKey())
+            .between(params.get("beginTime") != null && params.get("endTime") != null,
+                "r.create_time", params.get("beginTime"), params.get("endTime"))
+            .orderByAsc("r.role_sort").orderByAsc("r.create_time");;
+        return wrapper;
+    }
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鏌ヨ瑙掕壊
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 瑙掕壊鍒楄〃
+     */
+    @Override
+    public List<SysRoleVo> selectRolesByUserId(Long userId) {
+        List<SysRoleVo> userRoles = baseMapper.selectRolePermissionByUserId(userId);
+        List<SysRoleVo> roles = selectRoleAll();
+        for (SysRoleVo role : roles) {
+            for (SysRoleVo userRole : userRoles) {
+                if (role.getRoleId().longValue() == userRole.getRoleId().longValue()) {
+                    role.setFlag(true);
+                    break;
+                }
+            }
+        }
+        return roles;
+    }
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鏌ヨ鏉冮檺
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 鏉冮檺鍒楄〃
+     */
+    @Override
+    public Set<String> selectRolePermissionByUserId(Long userId) {
+        List<SysRoleVo> perms = baseMapper.selectRolePermissionByUserId(userId);
+        Set<String> permsSet = new HashSet<>();
+        for (SysRoleVo perm : perms) {
+            if (ObjectUtil.isNotNull(perm)) {
+                permsSet.addAll(StringUtils.splitList(perm.getRoleKey().trim()));
+            }
+        }
+        return permsSet;
+    }
+
+    /**
+     * 鏌ヨ鎵�鏈夎鑹�
+     *
+     * @return 瑙掕壊鍒楄〃
+     */
+    @Override
+    public List<SysRoleVo> selectRoleAll() {
+        return this.selectRoleList(new SysRoleBo());
+    }
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鑾峰彇瑙掕壊閫夋嫨妗嗗垪琛�
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 閫変腑瑙掕壊ID鍒楄〃
+     */
+    @Override
+    public List<Long> selectRoleListByUserId(Long userId) {
+        return baseMapper.selectRoleListByUserId(userId);
+    }
+
+    /**
+     * 閫氳繃瑙掕壊ID鏌ヨ瑙掕壊
+     *
+     * @param roleId 瑙掕壊ID
+     * @return 瑙掕壊瀵硅薄淇℃伅
+     */
+    @Override
+    public SysRoleVo selectRoleById(Long roleId) {
+        return baseMapper.selectRoleById(roleId);
+    }
+
+    /**
+     * 鏍¢獙瑙掕壊鍚嶇О鏄惁鍞竴
+     *
+     * @param role 瑙掕壊淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    public boolean checkRoleNameUnique(SysRoleBo role) {
+        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysRole>()
+            .eq(SysRole::getRoleName, role.getRoleName())
+            .ne(ObjectUtil.isNotNull(role.getRoleId()), SysRole::getRoleId, role.getRoleId()));
+        return !exist;
+    }
+
+    /**
+     * 鏍¢獙瑙掕壊鏉冮檺鏄惁鍞竴
+     *
+     * @param role 瑙掕壊淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    public boolean checkRoleKeyUnique(SysRoleBo role) {
+        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysRole>()
+            .eq(SysRole::getRoleKey, role.getRoleKey())
+            .ne(ObjectUtil.isNotNull(role.getRoleId()), SysRole::getRoleId, role.getRoleId()));
+        return !exist;
+    }
+
+    /**
+     * 鏍¢獙瑙掕壊鏄惁鍏佽鎿嶄綔
+     *
+     * @param roleId 瑙掕壊ID
+     */
+    @Override
+    public void checkRoleAllowed(Long roleId) {
+        if (ObjectUtil.isNotNull(roleId) && LoginHelper.isSuperAdmin(roleId)) {
+            throw new ServiceException("涓嶅厑璁告搷浣滆秴绾х鐞嗗憳瑙掕壊");
+        }
+    }
+
+    /**
+     * 鏍¢獙瑙掕壊鏄惁鏈夋暟鎹潈闄�
+     *
+     * @param roleId 瑙掕壊id
+     */
+    @Override
+    public void checkRoleDataScope(Long roleId) {
+        if (ObjectUtil.isNull(roleId)) {
+            return;
+        }
+        if (LoginHelper.isSuperAdmin()) {
+            return;
+        }
+        List<SysRoleVo> roles = this.selectRoleList(new SysRoleBo(roleId));
+        if (CollUtil.isEmpty(roles)) {
+            throw new ServiceException("娌℃湁鏉冮檺璁块棶瑙掕壊鏁版嵁锛�");
+        }
+
+    }
+
+    /**
+     * 閫氳繃瑙掕壊ID鏌ヨ瑙掕壊浣跨敤鏁伴噺
+     *
+     * @param roleId 瑙掕壊ID
+     * @return 缁撴灉
+     */
+    @Override
+    public long countUserRoleByRoleId(Long roleId) {
+        return userRoleMapper.selectCount(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getRoleId, roleId));
+    }
+
+    /**
+     * 鏂板淇濆瓨瑙掕壊淇℃伅
+     *
+     * @param bo 瑙掕壊淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int insertRole(SysRoleBo bo) {
+        SysRole role = MapstructUtils.convert(bo, SysRole.class);
+        // 鏂板瑙掕壊淇℃伅
+        baseMapper.insert(role);
+        bo.setRoleId(role.getRoleId());
+        return insertRoleMenu(bo);
+    }
+
+    /**
+     * 淇敼淇濆瓨瑙掕壊淇℃伅
+     *
+     * @param bo 瑙掕壊淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int updateRole(SysRoleBo bo) {
+        SysRole role = MapstructUtils.convert(bo, SysRole.class);
+        // 淇敼瑙掕壊淇℃伅
+        baseMapper.updateById(role);
+        // 鍒犻櫎瑙掕壊涓庤彍鍗曞叧鑱�
+        roleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, role.getRoleId()));
+        return insertRoleMenu(bo);
+    }
+
+    /**
+     * 淇敼瑙掕壊鐘舵��
+     *
+     * @param roleId 瑙掕壊ID
+     * @param status 瑙掕壊鐘舵��
+     * @return 缁撴灉
+     */
+    @Override
+    public int updateRoleStatus(Long roleId, String status) {
+        return baseMapper.update(null,
+            new LambdaUpdateWrapper<SysRole>()
+                .set(SysRole::getStatus, status)
+                .eq(SysRole::getRoleId, roleId));
+    }
+
+    /**
+     * 淇敼鏁版嵁鏉冮檺淇℃伅
+     *
+     * @param bo 瑙掕壊淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int authDataScope(SysRoleBo bo) {
+        SysRole role = MapstructUtils.convert(bo, SysRole.class);
+        // 淇敼瑙掕壊淇℃伅
+        baseMapper.updateById(role);
+        // 鍒犻櫎瑙掕壊涓庨儴闂ㄥ叧鑱�
+        roleDeptMapper.delete(new LambdaQueryWrapper<SysRoleDept>().eq(SysRoleDept::getRoleId, role.getRoleId()));
+        // 鏂板瑙掕壊鍜岄儴闂ㄤ俊鎭紙鏁版嵁鏉冮檺锛�
+        return insertRoleDept(bo);
+    }
+
+    /**
+     * 鏂板瑙掕壊鑿滃崟淇℃伅
+     *
+     * @param role 瑙掕壊瀵硅薄
+     */
+    private int insertRoleMenu(SysRoleBo role) {
+        int rows = 1;
+        // 鏂板鐢ㄦ埛涓庤鑹茬鐞�
+        List<SysRoleMenu> list = new ArrayList<SysRoleMenu>();
+        for (Long menuId : role.getMenuIds()) {
+            SysRoleMenu rm = new SysRoleMenu();
+            rm.setRoleId(role.getRoleId());
+            rm.setMenuId(menuId);
+            list.add(rm);
+        }
+        if (list.size() > 0) {
+            rows = roleMenuMapper.insertBatch(list) ? list.size() : 0;
+        }
+        return rows;
+    }
+
+    /**
+     * 鏂板瑙掕壊閮ㄩ棬淇℃伅(鏁版嵁鏉冮檺)
+     *
+     * @param role 瑙掕壊瀵硅薄
+     */
+    private int insertRoleDept(SysRoleBo role) {
+        int rows = 1;
+        // 鏂板瑙掕壊涓庨儴闂紙鏁版嵁鏉冮檺锛夌鐞�
+        List<SysRoleDept> list = new ArrayList<SysRoleDept>();
+        for (Long deptId : role.getDeptIds()) {
+            SysRoleDept rd = new SysRoleDept();
+            rd.setRoleId(role.getRoleId());
+            rd.setDeptId(deptId);
+            list.add(rd);
+        }
+        if (list.size() > 0) {
+            rows = roleDeptMapper.insertBatch(list) ? list.size() : 0;
+        }
+        return rows;
+    }
+
+    /**
+     * 閫氳繃瑙掕壊ID鍒犻櫎瑙掕壊
+     *
+     * @param roleId 瑙掕壊ID
+     * @return 缁撴灉
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int deleteRoleById(Long roleId) {
+        // 鍒犻櫎瑙掕壊涓庤彍鍗曞叧鑱�
+        roleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, roleId));
+        // 鍒犻櫎瑙掕壊涓庨儴闂ㄥ叧鑱�
+        roleDeptMapper.delete(new LambdaQueryWrapper<SysRoleDept>().eq(SysRoleDept::getRoleId, roleId));
+        return baseMapper.deleteById(roleId);
+    }
+
+    /**
+     * 鎵归噺鍒犻櫎瑙掕壊淇℃伅
+     *
+     * @param roleIds 闇�瑕佸垹闄ょ殑瑙掕壊ID
+     * @return 缁撴灉
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int deleteRoleByIds(Long[] roleIds) {
+        for (Long roleId : roleIds) {
+            checkRoleAllowed(roleId);
+            checkRoleDataScope(roleId);
+            SysRole role = baseMapper.selectById(roleId);
+            if (countUserRoleByRoleId(roleId) > 0) {
+                throw new ServiceException(String.format("%1$s宸插垎閰�,涓嶈兘鍒犻櫎", role.getRoleName()));
+            }
+        }
+        List<Long> ids = Arrays.asList(roleIds);
+        // 鍒犻櫎瑙掕壊涓庤彍鍗曞叧鑱�
+        roleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getRoleId, ids));
+        // 鍒犻櫎瑙掕壊涓庨儴闂ㄥ叧鑱�
+        roleDeptMapper.delete(new LambdaQueryWrapper<SysRoleDept>().in(SysRoleDept::getRoleId, ids));
+        return baseMapper.deleteBatchIds(ids);
+    }
+
+    /**
+     * 鍙栨秷鎺堟潈鐢ㄦ埛瑙掕壊
+     *
+     * @param userRole 鐢ㄦ埛鍜岃鑹插叧鑱斾俊鎭�
+     * @return 缁撴灉
+     */
+    @Override
+    public int deleteAuthUser(SysUserRole userRole) {
+        return userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
+            .eq(SysUserRole::getRoleId, userRole.getRoleId())
+            .eq(SysUserRole::getUserId, userRole.getUserId()));
+    }
+
+    /**
+     * 鎵归噺鍙栨秷鎺堟潈鐢ㄦ埛瑙掕壊
+     *
+     * @param roleId  瑙掕壊ID
+     * @param userIds 闇�瑕佸彇娑堟巿鏉冪殑鐢ㄦ埛鏁版嵁ID
+     * @return 缁撴灉
+     */
+    @Override
+    public int deleteAuthUsers(Long roleId, Long[] userIds) {
+        return userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
+            .eq(SysUserRole::getRoleId, roleId)
+            .in(SysUserRole::getUserId, Arrays.asList(userIds)));
+    }
+
+    /**
+     * 鎵归噺閫夋嫨鎺堟潈鐢ㄦ埛瑙掕壊
+     *
+     * @param roleId  瑙掕壊ID
+     * @param userIds 闇�瑕佹巿鏉冪殑鐢ㄦ埛鏁版嵁ID
+     * @return 缁撴灉
+     */
+    @Override
+    public int insertAuthUsers(Long roleId, Long[] userIds) {
+        // 鏂板鐢ㄦ埛涓庤鑹茬鐞�
+        int rows = 1;
+        List<SysUserRole> list = StreamUtils.toList(List.of(userIds), userId -> {
+            SysUserRole ur = new SysUserRole();
+            ur.setUserId(userId);
+            ur.setRoleId(roleId);
+            return ur;
+        });
+        if (CollUtil.isNotEmpty(list)) {
+            rows = userRoleMapper.insertBatch(list) ? list.size() : 0;
+        }
+        return rows;
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSensitiveServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSensitiveServiceImpl.java
new file mode 100644
index 0000000..296574b
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSensitiveServiceImpl.java
@@ -0,0 +1,26 @@
+package org.dromara.system.service.impl;
+
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.common.sensitive.core.SensitiveService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 鑴辨晱鏈嶅姟
+ * 榛樿绠$悊鍛樹笉杩囨护
+ * 闇�鑷鏍规嵁涓氬姟閲嶅啓瀹炵幇
+ *
+ * @author Lion Li
+ * @version 3.6.0
+ */
+@Service
+public class SysSensitiveServiceImpl implements SensitiveService {
+
+    /**
+     * 鏄惁鑴辨晱
+     */
+    @Override
+    public boolean isSensitive() {
+        return !LoginHelper.isSuperAdmin() || !LoginHelper.isTenantAdmin();
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantPackageServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantPackageServiceImpl.java
new file mode 100644
index 0000000..8b9224b
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantPackageServiceImpl.java
@@ -0,0 +1,139 @@
+package org.dromara.system.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import org.dromara.system.domain.SysTenant;
+import org.dromara.system.mapper.SysTenantMapper;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.dromara.system.domain.bo.SysTenantPackageBo;
+import org.dromara.system.domain.vo.SysTenantPackageVo;
+import org.dromara.system.domain.SysTenantPackage;
+import org.dromara.system.mapper.SysTenantPackageMapper;
+import org.dromara.system.service.ISysTenantPackageService;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 绉熸埛濂楅Service涓氬姟灞傚鐞�
+ *
+ * @author Michelle.Chung
+ */
+@RequiredArgsConstructor
+@Service
+public class SysTenantPackageServiceImpl implements ISysTenantPackageService {
+
+    private final SysTenantPackageMapper baseMapper;
+    private final SysTenantMapper tenantMapper;
+
+    /**
+     * 鏌ヨ绉熸埛濂楅
+     */
+    @Override
+    public SysTenantPackageVo queryById(Long packageId){
+        return baseMapper.selectVoById(packageId);
+    }
+
+    /**
+     * 鏌ヨ绉熸埛濂楅鍒楄〃
+     */
+    @Override
+    public TableDataInfo<SysTenantPackageVo> queryPageList(SysTenantPackageBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<SysTenantPackage> lqw = buildQueryWrapper(bo);
+        Page<SysTenantPackageVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 鏌ヨ绉熸埛濂楅鍒楄〃
+     */
+    @Override
+    public List<SysTenantPackageVo> queryList(SysTenantPackageBo bo) {
+        LambdaQueryWrapper<SysTenantPackage> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<SysTenantPackage> buildQueryWrapper(SysTenantPackageBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<SysTenantPackage> lqw = Wrappers.lambdaQuery();
+        lqw.like(StringUtils.isNotBlank(bo.getPackageName()), SysTenantPackage::getPackageName, bo.getPackageName());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysTenantPackage::getStatus, bo.getStatus());
+        return lqw;
+    }
+
+    /**
+     * 鏂板绉熸埛濂楅
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean insertByBo(SysTenantPackageBo bo) {
+        SysTenantPackage add = MapstructUtils.convert(bo, SysTenantPackage.class);
+        // 淇濆瓨鑿滃崟id
+        List<Long> menuIds = Arrays.asList(bo.getMenuIds());
+        if (CollUtil.isNotEmpty(menuIds)) {
+            add.setMenuIds(StringUtils.join(menuIds, ", "));
+        } else {
+            add.setMenuIds("");
+        }
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setPackageId(add.getPackageId());
+        }
+        return flag;
+    }
+
+    /**
+     * 淇敼绉熸埛濂楅
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean updateByBo(SysTenantPackageBo bo) {
+        SysTenantPackage update = MapstructUtils.convert(bo, SysTenantPackage.class);
+        // 淇濆瓨鑿滃崟id
+        List<Long> menuIds = Arrays.asList(bo.getMenuIds());
+        if (CollUtil.isNotEmpty(menuIds)) {
+            update.setMenuIds(StringUtils.join(menuIds, ", "));
+        } else {
+            update.setMenuIds("");
+        }
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 淇敼濂楅鐘舵��
+     *
+     * @param bo 濂楅淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    public int updatePackageStatus(SysTenantPackageBo bo) {
+        SysTenantPackage tenantPackage = MapstructUtils.convert(bo, SysTenantPackage.class);
+        return baseMapper.updateById(tenantPackage);
+    }
+
+    /**
+     * 鎵归噺鍒犻櫎绉熸埛濂楅
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            boolean exists = tenantMapper.exists(new LambdaQueryWrapper<SysTenant>().in(SysTenant::getPackageId, ids));
+            if (exists) {
+                throw new ServiceException("绉熸埛濂楅宸茶浣跨敤");
+            }
+        }
+        return baseMapper.deleteBatchIds(ids) > 0;
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantServiceImpl.java
new file mode 100644
index 0000000..703dc40
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantServiceImpl.java
@@ -0,0 +1,375 @@
+package org.dromara.system.service.impl;
+
+import cn.dev33.satoken.secure.BCrypt;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.RandomUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.constant.CacheNames;
+import org.dromara.common.core.constant.Constants;
+import org.dromara.common.core.constant.TenantConstants;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.tenant.helper.TenantHelper;
+import org.dromara.system.domain.*;
+import org.dromara.system.domain.bo.SysTenantBo;
+import org.dromara.system.domain.vo.SysTenantVo;
+import org.dromara.system.mapper.*;
+import org.dromara.system.service.ISysTenantService;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 绉熸埛Service涓氬姟灞傚鐞�
+ *
+ * @author Michelle.Chung
+ */
+@RequiredArgsConstructor
+@Service
+public class SysTenantServiceImpl implements ISysTenantService {
+
+    private final SysTenantMapper baseMapper;
+    private final SysTenantPackageMapper tenantPackageMapper;
+    private final SysUserMapper userMapper;
+    private final SysDeptMapper deptMapper;
+    private final SysRoleMapper roleMapper;
+    private final SysRoleMenuMapper roleMenuMapper;
+    private final SysRoleDeptMapper roleDeptMapper;
+    private final SysUserRoleMapper userRoleMapper;
+    private final SysDictTypeMapper dictTypeMapper;
+    private final SysDictDataMapper dictDataMapper;
+    private final SysConfigMapper configMapper;
+
+    /**
+     * 鏌ヨ绉熸埛
+     */
+    @Override
+    public SysTenantVo queryById(Long id) {
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 鍩轰簬绉熸埛ID鏌ヨ绉熸埛
+     */
+    @Cacheable(cacheNames = CacheNames.SYS_TENANT, key = "#tenantId")
+    @Override
+    public SysTenantVo queryByTenantId(String tenantId) {
+        return baseMapper.selectVoOne(new LambdaQueryWrapper<SysTenant>().eq(SysTenant::getTenantId, tenantId));
+    }
+
+    /**
+     * 鏌ヨ绉熸埛鍒楄〃
+     */
+    @Override
+    public TableDataInfo<SysTenantVo> queryPageList(SysTenantBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<SysTenant> lqw = buildQueryWrapper(bo);
+        Page<SysTenantVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 鏌ヨ绉熸埛鍒楄〃
+     */
+    @Override
+    public List<SysTenantVo> queryList(SysTenantBo bo) {
+        LambdaQueryWrapper<SysTenant> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<SysTenant> buildQueryWrapper(SysTenantBo bo) {
+        LambdaQueryWrapper<SysTenant> lqw = Wrappers.lambdaQuery();
+        lqw.eq(StringUtils.isNotBlank(bo.getTenantId()), SysTenant::getTenantId, bo.getTenantId());
+        lqw.like(StringUtils.isNotBlank(bo.getContactUserName()), SysTenant::getContactUserName, bo.getContactUserName());
+        lqw.eq(StringUtils.isNotBlank(bo.getContactPhone()), SysTenant::getContactPhone, bo.getContactPhone());
+        lqw.like(StringUtils.isNotBlank(bo.getCompanyName()), SysTenant::getCompanyName, bo.getCompanyName());
+        lqw.eq(StringUtils.isNotBlank(bo.getLicenseNumber()), SysTenant::getLicenseNumber, bo.getLicenseNumber());
+        lqw.eq(StringUtils.isNotBlank(bo.getAddress()), SysTenant::getAddress, bo.getAddress());
+        lqw.eq(StringUtils.isNotBlank(bo.getIntro()), SysTenant::getIntro, bo.getIntro());
+        lqw.like(StringUtils.isNotBlank(bo.getDomain()), SysTenant::getDomain, bo.getDomain());
+        lqw.eq(bo.getPackageId() != null, SysTenant::getPackageId, bo.getPackageId());
+        lqw.eq(bo.getExpireTime() != null, SysTenant::getExpireTime, bo.getExpireTime());
+        lqw.eq(bo.getAccountCount() != null, SysTenant::getAccountCount, bo.getAccountCount());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysTenant::getStatus, bo.getStatus());
+        return lqw;
+    }
+
+    /**
+     * 鏂板绉熸埛
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean insertByBo(SysTenantBo bo) {
+        TenantHelper.enableIgnore();
+
+        SysTenant add = MapstructUtils.convert(bo, SysTenant.class);
+
+        // 鑾峰彇鎵�鏈夌鎴风紪鍙�
+        List<String> tenantIds = baseMapper.selectObjs(
+            new LambdaQueryWrapper<SysTenant>().select(SysTenant::getTenantId), Convert::toStr);
+        String tenantId = generateTenantId(tenantIds);
+        add.setTenantId(tenantId);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (!flag) {
+            TenantHelper.disableIgnore();
+            throw new ServiceException("鍒涘缓绉熸埛澶辫触");
+        }
+        bo.setId(add.getId());
+
+        // 鏍规嵁濂楅鍒涘缓瑙掕壊
+        Long roleId = createTenantRole(tenantId, bo.getPackageId());
+
+        // 鍒涘缓閮ㄩ棬: 鍏徃鍚嶆槸閮ㄩ棬鍚嶇О
+        SysDept dept = new SysDept();
+        dept.setTenantId(tenantId);
+        dept.setDeptName(bo.getCompanyName());
+        dept.setLeader(bo.getUsername());
+        dept.setParentId(Constants.TOP_PARENT_ID);
+        dept.setAncestors(Constants.TOP_PARENT_ID.toString());
+        deptMapper.insert(dept);
+        Long deptId = dept.getDeptId();
+
+        // 瑙掕壊鍜岄儴闂ㄥ叧鑱旇〃
+        SysRoleDept roleDept = new SysRoleDept();
+        roleDept.setRoleId(roleId);
+        roleDept.setDeptId(deptId);
+        roleDeptMapper.insert(roleDept);
+
+        // 鍒涘缓绯荤粺鐢ㄦ埛
+        SysUser user = new SysUser();
+        user.setTenantId(tenantId);
+        user.setUserName(bo.getUsername());
+        user.setNickName(bo.getUsername());
+        user.setPassword(BCrypt.hashpw(bo.getPassword()));
+        user.setDeptId(deptId);
+        userMapper.insert(user);
+
+        // 鐢ㄦ埛鍜岃鑹插叧鑱旇〃
+        SysUserRole userRole = new SysUserRole();
+        userRole.setUserId(user.getUserId());
+        userRole.setRoleId(roleId);
+        userRoleMapper.insert(userRole);
+
+        String defaultTenantId = TenantConstants.DEFAULT_TENANT_ID;
+        List<SysDictType> dictTypeList = dictTypeMapper.selectList(
+            new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getTenantId, defaultTenantId));
+        List<SysDictData> dictDataList = dictDataMapper.selectList(
+            new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getTenantId, defaultTenantId));
+        for (SysDictType dictType : dictTypeList) {
+            dictType.setDictId(null);
+            dictType.setTenantId(tenantId);
+        }
+        for (SysDictData dictData : dictDataList) {
+            dictData.setDictCode(null);
+            dictData.setTenantId(tenantId);
+        }
+        dictTypeMapper.insertBatch(dictTypeList);
+        dictDataMapper.insertBatch(dictDataList);
+
+        List<SysConfig> sysConfigList = configMapper.selectList(
+            new LambdaQueryWrapper<SysConfig>().eq(SysConfig::getTenantId, defaultTenantId));
+        for (SysConfig config : sysConfigList) {
+            config.setConfigId(null);
+            config.setTenantId(tenantId);
+        }
+        configMapper.insertBatch(sysConfigList);
+
+        TenantHelper.disableIgnore();
+        return true;
+    }
+
+    /**
+     * 鐢熸垚绉熸埛id
+     *
+     * @param tenantIds 宸叉湁绉熸埛id鍒楄〃
+     * @return 绉熸埛id
+     */
+    private String generateTenantId(List<String> tenantIds) {
+        // 闅忔満鐢熸垚6浣�
+        String numbers = RandomUtil.randomNumbers(6);
+        // 鍒ゆ柇鏄惁瀛樺湪锛屽鏋滃瓨鍦ㄥ垯閲嶆柊鐢熸垚
+        if (tenantIds.contains(numbers)) {
+            generateTenantId(tenantIds);
+        }
+        return numbers;
+    }
+
+    /**
+     * 鏍规嵁绉熸埛鑿滃崟鍒涘缓绉熸埛瑙掕壊
+     *
+     * @param tenantId  绉熸埛缂栧彿
+     * @param packageId 绉熸埛濂楅id
+     * @return 瑙掕壊id
+     */
+    private Long createTenantRole(String tenantId, Long packageId) {
+        // 鑾峰彇绉熸埛濂楅
+        SysTenantPackage tenantPackage = tenantPackageMapper.selectById(packageId);
+        if (ObjectUtil.isNull(tenantPackage)) {
+            throw new ServiceException("濂楅涓嶅瓨鍦�");
+        }
+        // 鑾峰彇濂楅鑿滃崟id
+        List<Long> menuIds = StringUtils.splitTo(tenantPackage.getMenuIds(), Convert::toLong);
+
+        // 鍒涘缓瑙掕壊
+        SysRole role = new SysRole();
+        role.setTenantId(tenantId);
+        role.setRoleName(TenantConstants.TENANT_ADMIN_ROLE_NAME);
+        role.setRoleKey(TenantConstants.TENANT_ADMIN_ROLE_KEY);
+        role.setRoleSort(1);
+        role.setStatus(TenantConstants.NORMAL);
+        roleMapper.insert(role);
+        Long roleId = role.getRoleId();
+
+        // 鍒涘缓瑙掕壊鑿滃崟
+        List<SysRoleMenu> roleMenus = new ArrayList<>(menuIds.size());
+        menuIds.forEach(menuId -> {
+            SysRoleMenu roleMenu = new SysRoleMenu();
+            roleMenu.setRoleId(roleId);
+            roleMenu.setMenuId(menuId);
+            roleMenus.add(roleMenu);
+        });
+        roleMenuMapper.insertBatch(roleMenus);
+
+        return roleId;
+    }
+
+    /**
+     * 淇敼绉熸埛
+     */
+    @CacheEvict(cacheNames = CacheNames.SYS_TENANT, key = "#bo.tenantId")
+    @Override
+    public Boolean updateByBo(SysTenantBo bo) {
+        SysTenant tenant = MapstructUtils.convert(bo, SysTenant.class);
+        tenant.setTenantId(null);
+        tenant.setPackageId(null);
+        return baseMapper.updateById(tenant) > 0;
+    }
+
+    /**
+     * 淇敼绉熸埛鐘舵��
+     *
+     * @param bo 绉熸埛淇℃伅
+     * @return 缁撴灉
+     */
+    @CacheEvict(cacheNames = CacheNames.SYS_TENANT, key = "#bo.tenantId")
+    @Override
+    public int updateTenantStatus(SysTenantBo bo) {
+        SysTenant tenant = MapstructUtils.convert(bo, SysTenant.class);
+        return baseMapper.updateById(tenant);
+    }
+
+    /**
+     * 鏍¢獙绉熸埛鏄惁鍏佽鎿嶄綔
+     *
+     * @param tenantId 绉熸埛ID
+     */
+    @Override
+    public void checkTenantAllowed(String tenantId) {
+        if (ObjectUtil.isNotNull(tenantId) && TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) {
+            throw new ServiceException("涓嶅厑璁告搷浣滅鐞嗙鎴�");
+        }
+    }
+
+    /**
+     * 鎵归噺鍒犻櫎绉熸埛
+     */
+    @CacheEvict(cacheNames = CacheNames.SYS_TENANT, allEntries = true)
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            // 鍋氫竴浜涗笟鍔′笂鐨勬牎楠�,鍒ゆ柇鏄惁闇�瑕佹牎楠�
+            if (ids.contains(TenantConstants.SUPER_ADMIN_ID)) {
+                throw new ServiceException("瓒呯绉熸埛涓嶈兘鍒犻櫎");
+            }
+        }
+        return baseMapper.deleteBatchIds(ids) > 0;
+    }
+
+    /**
+     * 鏍¢獙浼佷笟鍚嶇О鏄惁鍞竴
+     */
+    @Override
+    public boolean checkCompanyNameUnique(SysTenantBo bo) {
+        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysTenant>()
+            .eq(SysTenant::getCompanyName, bo.getCompanyName())
+            .ne(ObjectUtil.isNotNull(bo.getTenantId()), SysTenant::getTenantId, bo.getTenantId()));
+        return !exist;
+    }
+
+    /**
+     * 鏍¢獙璐﹀彿浣欓
+     */
+    @Override
+    public boolean checkAccountBalance(String tenantId) {
+        SysTenantVo tenant = SpringUtils.getAopProxy(this).queryByTenantId(tenantId);
+        // 濡傛灉浣欓涓�-1浠h〃涓嶉檺鍒�
+        if (tenant.getAccountCount() == -1) {
+            return true;
+        }
+        Long userNumber = userMapper.selectCount(new LambdaQueryWrapper<>());
+        // 濡傛灉浣欓澶т簬0浠h〃杩樻湁鍙敤鍚嶉
+        return tenant.getAccountCount() - userNumber > 0;
+    }
+
+    /**
+     * 鏍¢獙鏈夋晥鏈�
+     */
+    @Override
+    public boolean checkExpireTime(String tenantId) {
+        SysTenantVo tenant = SpringUtils.getAopProxy(this).queryByTenantId(tenantId);
+        // 濡傛灉鏈缃繃鏈熸椂闂翠唬琛ㄤ笉闄愬埗
+        if (ObjectUtil.isNull(tenant.getExpireTime())) {
+            return true;
+        }
+        // 濡傛灉褰撳墠鏃堕棿鍦ㄨ繃鏈熸椂闂翠箣鍓嶅垯閫氳繃
+        return new Date().before(tenant.getExpireTime());
+    }
+
+    /**
+     * 鍚屾绉熸埛濂楅
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean syncTenantPackage(String tenantId, String packageId) {
+        TenantHelper.enableIgnore();
+        SysTenantPackage tenantPackage = tenantPackageMapper.selectById(packageId);
+        List<SysRole> roles = roleMapper.selectList(
+            new LambdaQueryWrapper<SysRole>().eq(SysRole::getTenantId, tenantId));
+        List<Long> roleIds = new ArrayList<>(roles.size() - 1);
+        List<Long> menuIds = StringUtils.splitTo(tenantPackage.getMenuIds(), Convert::toLong);
+        roles.forEach(item -> {
+            if (TenantConstants.TENANT_ADMIN_ROLE_KEY.equals(item.getRoleKey())) {
+                List<SysRoleMenu> roleMenus = new ArrayList<>(menuIds.size());
+                menuIds.forEach(menuId -> {
+                    SysRoleMenu roleMenu = new SysRoleMenu();
+                    roleMenu.setRoleId(item.getRoleId());
+                    roleMenu.setMenuId(menuId);
+                    roleMenus.add(roleMenu);
+                });
+                roleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, item.getRoleId()));
+                roleMenuMapper.insertBatch(roleMenus);
+            } else {
+                roleIds.add(item.getRoleId());
+            }
+        });
+        if (!roleIds.isEmpty()) {
+            roleMenuMapper.delete(
+                new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getRoleId, roleIds).notIn(!menuIds.isEmpty(), SysRoleMenu::getMenuId, menuIds));
+        }
+        TenantHelper.disableIgnore();
+        return true;
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java
new file mode 100644
index 0000000..57d562f
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java
@@ -0,0 +1,525 @@
+package org.dromara.system.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.constant.CacheNames;
+import org.dromara.common.core.constant.UserConstants;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.service.UserService;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StreamUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.helper.DataBaseHelper;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.system.domain.SysDept;
+import org.dromara.system.domain.SysUser;
+import org.dromara.system.domain.SysUserPost;
+import org.dromara.system.domain.SysUserRole;
+import org.dromara.system.domain.bo.SysUserBo;
+import org.dromara.system.domain.vo.SysPostVo;
+import org.dromara.system.domain.vo.SysRoleVo;
+import org.dromara.system.domain.vo.SysUserVo;
+import org.dromara.system.mapper.*;
+import org.dromara.system.service.ISysUserService;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 鐢ㄦ埛 涓氬姟灞傚鐞�
+ *
+ * @author Lion Li
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class SysUserServiceImpl implements ISysUserService, UserService {
+
+    private final SysUserMapper baseMapper;
+    private final SysDeptMapper deptMapper;
+    private final SysRoleMapper roleMapper;
+    private final SysPostMapper postMapper;
+    private final SysUserRoleMapper userRoleMapper;
+    private final SysUserPostMapper userPostMapper;
+
+    @Override
+    public TableDataInfo<SysUserVo> selectPageUserList(SysUserBo user, PageQuery pageQuery) {
+        Page<SysUserVo> page = baseMapper.selectPageUserList(pageQuery.build(), this.buildQueryWrapper(user));
+        return TableDataInfo.build(page);
+    }
+
+    /**
+     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ鐢ㄦ埛鍒楄〃
+     *
+     * @param user 鐢ㄦ埛淇℃伅
+     * @return 鐢ㄦ埛淇℃伅闆嗗悎淇℃伅
+     */
+    @Override
+    public List<SysUserVo> selectUserList(SysUserBo user) {
+        return baseMapper.selectUserList(this.buildQueryWrapper(user));
+    }
+
+    private Wrapper<SysUser> buildQueryWrapper(SysUserBo user) {
+        Map<String, Object> params = user.getParams();
+        QueryWrapper<SysUser> wrapper = Wrappers.query();
+        wrapper.eq("u.del_flag", UserConstants.USER_NORMAL)
+            .eq(ObjectUtil.isNotNull(user.getUserId()), "u.user_id", user.getUserId())
+            .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName())
+            .eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus())
+            .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber())
+            .between(params.get("beginTime") != null && params.get("endTime") != null,
+                "u.create_time", params.get("beginTime"), params.get("endTime"))
+            .and(ObjectUtil.isNotNull(user.getDeptId()), w -> {
+                List<SysDept> deptList = deptMapper.selectList(new LambdaQueryWrapper<SysDept>()
+                    .select(SysDept::getDeptId)
+                    .apply(DataBaseHelper.findInSet(user.getDeptId(), "ancestors")));
+                List<Long> ids = StreamUtils.toList(deptList, SysDept::getDeptId);
+                ids.add(user.getDeptId());
+                w.in("u.dept_id", ids);
+            });
+        return wrapper;
+    }
+
+    /**
+     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ宸插垎閰嶇敤鎴疯鑹插垪琛�
+     *
+     * @param user 鐢ㄦ埛淇℃伅
+     * @return 鐢ㄦ埛淇℃伅闆嗗悎淇℃伅
+     */
+    @Override
+    public TableDataInfo<SysUserVo> selectAllocatedList(SysUserBo user, PageQuery pageQuery) {
+        QueryWrapper<SysUser> wrapper = Wrappers.query();
+        wrapper.eq("u.del_flag", UserConstants.USER_NORMAL)
+            .eq(ObjectUtil.isNotNull(user.getRoleId()), "r.role_id", user.getRoleId())
+            .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName())
+            .eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus())
+            .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber());
+        Page<SysUserVo> page = baseMapper.selectAllocatedList(pageQuery.build(), wrapper);
+        return TableDataInfo.build(page);
+    }
+
+    /**
+     * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ鏈垎閰嶇敤鎴疯鑹插垪琛�
+     *
+     * @param user 鐢ㄦ埛淇℃伅
+     * @return 鐢ㄦ埛淇℃伅闆嗗悎淇℃伅
+     */
+    @Override
+    public TableDataInfo<SysUserVo> selectUnallocatedList(SysUserBo user, PageQuery pageQuery) {
+        List<Long> userIds = userRoleMapper.selectUserIdsByRoleId(user.getRoleId());
+        QueryWrapper<SysUser> wrapper = Wrappers.query();
+        wrapper.eq("u.del_flag", UserConstants.USER_NORMAL)
+            .and(w -> w.ne("r.role_id", user.getRoleId()).or().isNull("r.role_id"))
+            .notIn(CollUtil.isNotEmpty(userIds), "u.user_id", userIds)
+            .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName())
+            .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber());
+        Page<SysUserVo> page = baseMapper.selectUnallocatedList(pageQuery.build(), wrapper);
+        return TableDataInfo.build(page);
+    }
+
+    /**
+     * 閫氳繃鐢ㄦ埛鍚嶆煡璇㈢敤鎴�
+     *
+     * @param userName 鐢ㄦ埛鍚�
+     * @return 鐢ㄦ埛瀵硅薄淇℃伅
+     */
+    @Override
+    public SysUserVo selectUserByUserName(String userName) {
+        return baseMapper.selectUserByUserName(userName);
+    }
+
+    /**
+     * 閫氳繃鎵嬫満鍙锋煡璇㈢敤鎴�
+     *
+     * @param phonenumber 鎵嬫満鍙�
+     * @return 鐢ㄦ埛瀵硅薄淇℃伅
+     */
+    @Override
+    public SysUserVo selectUserByPhonenumber(String phonenumber) {
+        return baseMapper.selectUserByPhonenumber(phonenumber);
+    }
+
+    /**
+     * 閫氳繃鐢ㄦ埛ID鏌ヨ鐢ㄦ埛
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 鐢ㄦ埛瀵硅薄淇℃伅
+     */
+    @Override
+    public SysUserVo selectUserById(Long userId) {
+        return baseMapper.selectUserById(userId);
+    }
+
+    /**
+     * 鏌ヨ鐢ㄦ埛鎵�灞炶鑹茬粍
+     *
+     * @param userName 鐢ㄦ埛鍚�
+     * @return 缁撴灉
+     */
+    @Override
+    public String selectUserRoleGroup(String userName) {
+        List<SysRoleVo> list = roleMapper.selectRolesByUserName(userName);
+        if (CollUtil.isEmpty(list)) {
+            return StringUtils.EMPTY;
+        }
+        return StreamUtils.join(list, SysRoleVo::getRoleName);
+    }
+
+    /**
+     * 鏌ヨ鐢ㄦ埛鎵�灞炲矖浣嶇粍
+     *
+     * @param userName 鐢ㄦ埛鍚�
+     * @return 缁撴灉
+     */
+    @Override
+    public String selectUserPostGroup(String userName) {
+        List<SysPostVo> list = postMapper.selectPostsByUserName(userName);
+        if (CollUtil.isEmpty(list)) {
+            return StringUtils.EMPTY;
+        }
+        return StreamUtils.join(list, SysPostVo::getPostName);
+    }
+
+    /**
+     * 鏍¢獙鐢ㄦ埛鍚嶇О鏄惁鍞竴
+     *
+     * @param user 鐢ㄦ埛淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    public boolean checkUserNameUnique(SysUserBo user) {
+        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
+            .eq(SysUser::getUserName, user.getUserName())
+            .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId()));
+        return !exist;
+    }
+
+    /**
+     * 鏍¢獙鎵嬫満鍙风爜鏄惁鍞竴
+     *
+     * @param user 鐢ㄦ埛淇℃伅
+     */
+    @Override
+    public boolean checkPhoneUnique(SysUserBo user) {
+        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
+            .eq(SysUser::getPhonenumber, user.getPhonenumber())
+            .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId()));
+        return !exist;
+    }
+
+    /**
+     * 鏍¢獙email鏄惁鍞竴
+     *
+     * @param user 鐢ㄦ埛淇℃伅
+     */
+    @Override
+    public boolean checkEmailUnique(SysUserBo user) {
+        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
+            .eq(SysUser::getEmail, user.getEmail())
+            .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId()));
+        return !exist;
+    }
+
+    /**
+     * 鏍¢獙鐢ㄦ埛鏄惁鍏佽鎿嶄綔
+     *
+     * @param userId 鐢ㄦ埛ID
+     */
+    @Override
+    public void checkUserAllowed(Long userId) {
+        if (ObjectUtil.isNotNull(userId) && LoginHelper.isSuperAdmin(userId)) {
+            throw new ServiceException("涓嶅厑璁告搷浣滆秴绾х鐞嗗憳鐢ㄦ埛");
+        }
+    }
+
+    /**
+     * 鏍¢獙鐢ㄦ埛鏄惁鏈夋暟鎹潈闄�
+     *
+     * @param userId 鐢ㄦ埛id
+     */
+    @Override
+    public void checkUserDataScope(Long userId) {
+        if (ObjectUtil.isNull(userId)) {
+            return;
+        }
+        if (LoginHelper.isSuperAdmin()) {
+            return;
+        }
+        if (ObjectUtil.isNull(baseMapper.selectUserById(userId))) {
+            throw new ServiceException("娌℃湁鏉冮檺璁块棶鐢ㄦ埛鏁版嵁锛�");
+        }
+    }
+
+    /**
+     * 鏂板淇濆瓨鐢ㄦ埛淇℃伅
+     *
+     * @param user 鐢ㄦ埛淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int insertUser(SysUserBo user) {
+        SysUser sysUser = MapstructUtils.convert(user, SysUser.class);
+        // 鏂板鐢ㄦ埛淇℃伅
+        int rows = baseMapper.insert(sysUser);
+        user.setUserId(sysUser.getUserId());
+        // 鏂板鐢ㄦ埛宀椾綅鍏宠仈
+        insertUserPost(user, false);
+        // 鏂板鐢ㄦ埛涓庤鑹茬鐞�
+        insertUserRole(user, false);
+        return rows;
+    }
+
+    /**
+     * 娉ㄥ唽鐢ㄦ埛淇℃伅
+     *
+     * @param user 鐢ㄦ埛淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    public boolean registerUser(SysUserBo user, String tenantId) {
+        user.setCreateBy(user.getUserId());
+        user.setUpdateBy(user.getUserId());
+        SysUser sysUser = MapstructUtils.convert(user, SysUser.class);
+        sysUser.setTenantId(tenantId);
+        return baseMapper.insert(sysUser) > 0;
+    }
+
+    /**
+     * 淇敼淇濆瓨鐢ㄦ埛淇℃伅
+     *
+     * @param user 鐢ㄦ埛淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int updateUser(SysUserBo user) {
+        // 鏂板鐢ㄦ埛涓庤鑹茬鐞�
+        insertUserRole(user, true);
+        // 鏂板鐢ㄦ埛涓庡矖浣嶇鐞�
+        insertUserPost(user, true);
+        SysUser sysUser = MapstructUtils.convert(user, SysUser.class);
+        // 闃叉閿欒鏇存柊鍚庡鑷寸殑鏁版嵁璇垹闄�
+        int flag = baseMapper.updateById(sysUser);
+        if (flag < 1) {
+            throw new ServiceException("淇敼鐢ㄦ埛" + user.getUserName() + "淇℃伅澶辫触");
+        }
+        return flag;
+    }
+
+    /**
+     * 鐢ㄦ埛鎺堟潈瑙掕壊
+     *
+     * @param userId  鐢ㄦ埛ID
+     * @param roleIds 瑙掕壊缁�
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void insertUserAuth(Long userId, Long[] roleIds) {
+        userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
+            .eq(SysUserRole::getUserId, userId));
+        insertUserRole(userId, roleIds, false);
+    }
+
+    /**
+     * 淇敼鐢ㄦ埛鐘舵��
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @param status 甯愬彿鐘舵��
+     * @return 缁撴灉
+     */
+    @Override
+    public int updateUserStatus(Long userId, String status) {
+        return baseMapper.update(null,
+            new LambdaUpdateWrapper<SysUser>()
+                .set(SysUser::getStatus, status)
+                .eq(SysUser::getUserId, userId));
+    }
+
+    /**
+     * 淇敼鐢ㄦ埛鍩烘湰淇℃伅
+     *
+     * @param user 鐢ㄦ埛淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    public int updateUserProfile(SysUserBo user) {
+        return baseMapper.update(null,
+            new LambdaUpdateWrapper<SysUser>()
+                .set(ObjectUtil.isNotNull(user.getNickName()), SysUser::getNickName, user.getNickName())
+                .set(SysUser::getPhonenumber, user.getPhonenumber())
+                .set(SysUser::getEmail, user.getEmail())
+                .set(SysUser::getSex, user.getSex())
+                .eq(SysUser::getUserId, user.getUserId()));
+    }
+
+    /**
+     * 淇敼鐢ㄦ埛澶村儚
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @param avatar 澶村儚鍦板潃
+     * @return 缁撴灉
+     */
+    @Override
+    public boolean updateUserAvatar(Long userId, Long avatar) {
+        return baseMapper.update(null,
+            new LambdaUpdateWrapper<SysUser>()
+                .set(SysUser::getAvatar, avatar)
+                .eq(SysUser::getUserId, userId)) > 0;
+    }
+
+    /**
+     * 閲嶇疆鐢ㄦ埛瀵嗙爜
+     *
+     * @param userId   鐢ㄦ埛ID
+     * @param password 瀵嗙爜
+     * @return 缁撴灉
+     */
+    @Override
+    public int resetUserPwd(Long userId, String password) {
+        return baseMapper.update(null,
+            new LambdaUpdateWrapper<SysUser>()
+                .set(SysUser::getPassword, password)
+                .eq(SysUser::getUserId, userId));
+    }
+
+    /**
+     * 鏂板鐢ㄦ埛瑙掕壊淇℃伅
+     *
+     * @param user  鐢ㄦ埛瀵硅薄
+     * @param clear 娓呴櫎宸插瓨鍦ㄧ殑鍏宠仈鏁版嵁
+     */
+    private void insertUserRole(SysUserBo user, boolean clear) {
+        this.insertUserRole(user.getUserId(), user.getRoleIds(), clear);
+    }
+
+    /**
+     * 鏂板鐢ㄦ埛宀椾綅淇℃伅
+     *
+     * @param user  鐢ㄦ埛瀵硅薄
+     * @param clear 娓呴櫎宸插瓨鍦ㄧ殑鍏宠仈鏁版嵁
+     */
+    private void insertUserPost(SysUserBo user, boolean clear) {
+        Long[] posts = user.getPostIds();
+        if (ArrayUtil.isNotEmpty(posts)) {
+            if (clear) {
+                // 鍒犻櫎鐢ㄦ埛涓庡矖浣嶅叧鑱�
+                userPostMapper.delete(new LambdaQueryWrapper<SysUserPost>().eq(SysUserPost::getUserId, user.getUserId()));
+            }
+            // 鏂板鐢ㄦ埛涓庡矖浣嶇鐞�
+            List<SysUserPost> list = StreamUtils.toList(List.of(posts), postId -> {
+                SysUserPost up = new SysUserPost();
+                up.setUserId(user.getUserId());
+                up.setPostId(postId);
+                return up;
+            });
+            userPostMapper.insertBatch(list);
+        }
+    }
+
+    /**
+     * 鏂板鐢ㄦ埛瑙掕壊淇℃伅
+     *
+     * @param userId  鐢ㄦ埛ID
+     * @param roleIds 瑙掕壊缁�
+     * @param clear   娓呴櫎宸插瓨鍦ㄧ殑鍏宠仈鏁版嵁
+     */
+    private void insertUserRole(Long userId, Long[] roleIds, boolean clear) {
+        if (ArrayUtil.isNotEmpty(roleIds)) {
+            // 鍒ゆ柇鏄惁鍏锋湁姝よ鑹茬殑鎿嶄綔鏉冮檺
+            List<SysRoleVo> roles = roleMapper.selectRoleList(new LambdaQueryWrapper<>());
+            if (CollUtil.isEmpty(roles)) {
+                throw new ServiceException("娌℃湁鏉冮檺璁块棶瑙掕壊鐨勬暟鎹�");
+            }
+            List<Long> roleList = StreamUtils.toList(roles, SysRoleVo::getRoleId);
+            if (!LoginHelper.isSuperAdmin(userId)) {
+                roleList.remove(UserConstants.SUPER_ADMIN_ID);
+            }
+            List<Long> canDoRoleList = StreamUtils.filter(List.of(roleIds), roleList::contains);
+            if (CollUtil.isEmpty(canDoRoleList)) {
+                throw new ServiceException("娌℃湁鏉冮檺璁块棶瑙掕壊鐨勬暟鎹�");
+            }
+            if (clear) {
+                // 鍒犻櫎鐢ㄦ埛涓庤鑹插叧鑱�
+                userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
+            }
+            // 鏂板鐢ㄦ埛涓庤鑹茬鐞�
+            List<SysUserRole> list = StreamUtils.toList(canDoRoleList, roleId -> {
+                SysUserRole ur = new SysUserRole();
+                ur.setUserId(userId);
+                ur.setRoleId(roleId);
+                return ur;
+            });
+            userRoleMapper.insertBatch(list);
+        }
+    }
+
+    /**
+     * 閫氳繃鐢ㄦ埛ID鍒犻櫎鐢ㄦ埛
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 缁撴灉
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int deleteUserById(Long userId) {
+        // 鍒犻櫎鐢ㄦ埛涓庤鑹插叧鑱�
+        userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
+        // 鍒犻櫎鐢ㄦ埛涓庡矖浣嶈〃
+        userPostMapper.delete(new LambdaQueryWrapper<SysUserPost>().eq(SysUserPost::getUserId, userId));
+        // 闃叉鏇存柊澶辫触瀵艰嚧鐨勬暟鎹垹闄�
+        int flag = baseMapper.deleteById(userId);
+        if (flag < 1) {
+            throw new ServiceException("鍒犻櫎鐢ㄦ埛澶辫触!");
+        }
+        return flag;
+    }
+
+    /**
+     * 鎵归噺鍒犻櫎鐢ㄦ埛淇℃伅
+     *
+     * @param userIds 闇�瑕佸垹闄ょ殑鐢ㄦ埛ID
+     * @return 缁撴灉
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int deleteUserByIds(Long[] userIds) {
+        for (Long userId : userIds) {
+            checkUserAllowed(userId);
+            checkUserDataScope(userId);
+        }
+        List<Long> ids = List.of(userIds);
+        // 鍒犻櫎鐢ㄦ埛涓庤鑹插叧鑱�
+        userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getUserId, ids));
+        // 鍒犻櫎鐢ㄦ埛涓庡矖浣嶈〃
+        userPostMapper.delete(new LambdaQueryWrapper<SysUserPost>().in(SysUserPost::getUserId, ids));
+        // 闃叉鏇存柊澶辫触瀵艰嚧鐨勬暟鎹垹闄�
+        int flag = baseMapper.deleteBatchIds(ids);
+        if (flag < 1) {
+            throw new ServiceException("鍒犻櫎鐢ㄦ埛澶辫触!");
+        }
+        return flag;
+    }
+
+    @Cacheable(cacheNames = CacheNames.SYS_USER_NAME, key = "#userId")
+    @Override
+    public String selectUserNameById(Long userId) {
+        SysUser sysUser = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>()
+            .select(SysUser::getUserName).eq(SysUser::getUserId, userId));
+        return ObjectUtil.isNull(sysUser) ? null : sysUser.getUserName();
+    }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysConfigMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysConfigMapper.xml
index 766724e..e542a10 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysConfigMapper.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysConfigMapper.xml
@@ -2,6 +2,6 @@
 <!DOCTYPE mapper
         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.system.mapper.SysConfigMapper">
+<mapper namespace="org.dromara.system.mapper.SysConfigMapper">
 
 </mapper>
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml
index 131c8a3..bba949d 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml
@@ -2,9 +2,9 @@
 <!DOCTYPE mapper
         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.system.mapper.SysDeptMapper">
+<mapper namespace="org.dromara.system.mapper.SysDeptMapper">
 
-    <resultMap type="com.ruoyi.system.domain.vo.SysDeptVo" id="SysDeptResult">
+    <resultMap type="org.dromara.system.domain.vo.SysDeptVo" id="SysDeptResult">
     </resultMap>
 
     <select id="selectDeptList" resultMap="SysDeptResult">
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictDataMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictDataMapper.xml
index 1ebfad7..6bcce51 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictDataMapper.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictDataMapper.xml
@@ -2,6 +2,6 @@
 <!DOCTYPE mapper
         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.system.mapper.SysDictDataMapper">
+<mapper namespace="org.dromara.system.mapper.SysDictDataMapper">
 
 </mapper>
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictTypeMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictTypeMapper.xml
index 42b0405..6975da4 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictTypeMapper.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictTypeMapper.xml
@@ -2,6 +2,6 @@
 <!DOCTYPE mapper
         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.system.mapper.SysDictTypeMapper">
+<mapper namespace="org.dromara.system.mapper.SysDictTypeMapper">
 
 </mapper>
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysLogininforMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysLogininforMapper.xml
index 65ea938..c64b551 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysLogininforMapper.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysLogininforMapper.xml
@@ -2,6 +2,6 @@
 <!DOCTYPE mapper
         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.system.mapper.SysLogininforMapper">
+<mapper namespace="org.dromara.system.mapper.SysLogininforMapper">
 
 </mapper>
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml
index acd3b5e..fad1812 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml
@@ -2,9 +2,9 @@
 <!DOCTYPE mapper
         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.system.mapper.SysMenuMapper">
+<mapper namespace="org.dromara.system.mapper.SysMenuMapper">
 
-    <resultMap type="com.ruoyi.system.domain.SysMenu" id="SysMenuResult">
+    <resultMap type="org.dromara.system.domain.SysMenu" id="SysMenuResult">
     </resultMap>
 
     <select id="selectMenuListByUserId" resultMap="SysMenuResult">
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysNoticeMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysNoticeMapper.xml
index e7aeaf9..43f494d 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysNoticeMapper.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysNoticeMapper.xml
@@ -2,6 +2,6 @@
 <!DOCTYPE mapper
         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.system.mapper.SysNoticeMapper">
+<mapper namespace="org.dromara.system.mapper.SysNoticeMapper">
 
 </mapper>
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml
index af70259..5ef14ee 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml
@@ -2,6 +2,6 @@
 <!DOCTYPE mapper
         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.system.mapper.SysOperLogMapper">
+<mapper namespace="org.dromara.system.mapper.SysOperLogMapper">
 
 </mapper>
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOssConfigMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOssConfigMapper.xml
index 8af22fe..8c2c080 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOssConfigMapper.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOssConfigMapper.xml
@@ -2,6 +2,6 @@
 <!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.system.mapper.SysOssConfigMapper">
+<mapper namespace="org.dromara.system.mapper.SysOssConfigMapper">
 
 </mapper>
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOssMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOssMapper.xml
index 24714f6..d9b25bd 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOssMapper.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOssMapper.xml
@@ -1,5 +1,5 @@
 <?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.system.mapper.SysOssMapper">
+<mapper namespace="org.dromara.system.mapper.SysOssMapper">
 
 </mapper>
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml
index f142b8d..d2108eb 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml
@@ -2,9 +2,9 @@
 <!DOCTYPE mapper
         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.system.mapper.SysPostMapper">
+<mapper namespace="org.dromara.system.mapper.SysPostMapper">
 
-    <resultMap type="com.ruoyi.system.domain.vo.SysPostVo" id="SysPostResult">
+    <resultMap type="org.dromara.system.domain.vo.SysPostVo" id="SysPostResult">
     </resultMap>
 
     <select id="selectPostListByUserId" parameterType="Long" resultType="Long">
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml
index 94740f4..1705bb2 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml
@@ -2,6 +2,6 @@
 <!DOCTYPE mapper
         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.system.mapper.SysRoleDeptMapper">
+<mapper namespace="org.dromara.system.mapper.SysRoleDeptMapper">
 
 </mapper>
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml
index 388fe91..d482f39 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml
@@ -2,9 +2,9 @@
 <!DOCTYPE mapper
         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.system.mapper.SysRoleMapper">
+<mapper namespace="org.dromara.system.mapper.SysRoleMapper">
 
-    <resultMap type="com.ruoyi.system.domain.vo.SysRoleVo" id="SysRoleResult">
+    <resultMap type="org.dromara.system.domain.vo.SysRoleVo" id="SysRoleResult">
     </resultMap>
 
     <sql id="selectRoleVo">
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml
index e40a242..f01dc5e 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml
@@ -2,6 +2,6 @@
 <!DOCTYPE mapper
         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.system.mapper.SysRoleMenuMapper">
+<mapper namespace="org.dromara.system.mapper.SysRoleMenuMapper">
 
 </mapper>
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysTenantMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysTenantMapper.xml
index f3fa4cb..0d96e13 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysTenantMapper.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysTenantMapper.xml
@@ -2,6 +2,6 @@
 <!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.system.mapper.SysTenantMapper">
+<mapper namespace="org.dromara.system.mapper.SysTenantMapper">
 
 </mapper>
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysTenantPackageMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysTenantPackageMapper.xml
index 23b46df..79cf4c5 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysTenantPackageMapper.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysTenantPackageMapper.xml
@@ -2,6 +2,6 @@
 <!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.system.mapper.SysTenantPackageMapper">
+<mapper namespace="org.dromara.system.mapper.SysTenantPackageMapper">
 
 </mapper>
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
index 92d8c9e..32f3e31 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
@@ -2,21 +2,21 @@
 <!DOCTYPE mapper
         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.system.mapper.SysUserMapper">
+<mapper namespace="org.dromara.system.mapper.SysUserMapper">
 
     <!-- 澶氱粨鏋勫祵濂楄嚜鍔ㄦ槧灏勯渶甯︿笂姣忎釜瀹炰綋鐨勪富閿甶d 鍚﹀垯鏄犲皠浼氬け璐� -->
-    <resultMap type="com.ruoyi.system.domain.vo.SysUserVo" id="SysUserResult">
+    <resultMap type="org.dromara.system.domain.vo.SysUserVo" id="SysUserResult">
         <id property="userId" column="user_id"/>
         <result property="deptId" column="dept_id"/>
         <association property="dept" column="dept_id" resultMap="deptResult"/>
         <collection property="roles" javaType="java.util.List" resultMap="RoleResult"/>
     </resultMap>
 
-    <resultMap id="deptResult" type="com.ruoyi.system.domain.vo.SysDeptVo">
+    <resultMap id="deptResult" type="org.dromara.system.domain.vo.SysDeptVo">
         <id property="deptId" column="dept_id"/>
     </resultMap>
 
-    <resultMap id="RoleResult" type="com.ruoyi.system.domain.vo.SysRoleVo">
+    <resultMap id="RoleResult" type="org.dromara.system.domain.vo.SysRoleVo">
         <id property="roleId" column="role_id"/>
     </resultMap>
 
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml
index d6dffcd..e9f2496 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml
@@ -2,6 +2,6 @@
 <!DOCTYPE mapper
         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.system.mapper.SysUserPostMapper">
+<mapper namespace="org.dromara.system.mapper.SysUserPostMapper">
 
 </mapper>
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml
index a029d66..bc52d1a 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml
@@ -2,7 +2,7 @@
 <!DOCTYPE mapper
         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.system.mapper.SysUserRoleMapper">
+<mapper namespace="org.dromara.system.mapper.SysUserRoleMapper">
 
     <select id="selectUserIdsByRoleId" resultType="Long">
         select u.user_id from sys_user u

--
Gitblit v1.9.3