From 45ac0f23e12ac2a45c6affe9e39d0897e4fad618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Thu, 16 Feb 2023 09:06:10 +0000 Subject: [PATCH] =?UTF-8?q?!286=20=E5=90=88=E5=B9=B6=20=E5=A4=9A=E7=A7=9F?= =?UTF-8?q?=E6=88=B7=E5=8A=9F=E8=83=BD=20*=20add=20=E6=96=B0=E5=A2=9E=20ru?= =?UTF-8?q?oyi-common-tenant=20=E5=A4=9A=E7=A7=9F=E6=88=B7=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=20=E5=85=A8=E6=A1=86=E6=9E=B6=E9=80=82=E9=85=8D?= =?UTF-8?q?=E5=A4=9A=E7=A7=9F=E6=88=B7=E6=94=B9=E5=8A=A8=20*=20update=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=20=E9=9A=90=E8=97=8F=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E4=B8=BB=E9=94=AE=20*=20remove=20=E7=A7=BB=E9=99=A4=20?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E5=88=97=E8=A1=A8=E5=8A=9F=E8=83=BD(?= =?UTF-8?q?=E5=A4=9A=E7=A7=9F=E6=88=B7=E7=BC=93=E5=AD=98=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E7=B9=81=E6=9D=82=E5=A4=9A=E6=A0=B7=20=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E5=8A=9E=E6=B3=95=E5=9C=A8=E9=A1=B5=E9=9D=A2=E7=AE=A1=E7=90=86?= =?UTF-8?q?)=20*=20update=20=E9=87=8D=E6=9E=84=20=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E7=BC=93=E5=AD=98KEY=20=E4=B8=8E=20=E5=B8=B8=E7=94=A8=E7=BC=93?= =?UTF-8?q?=E5=AD=98KEY=E5=81=9A=E5=8C=BA=E5=88=86=20*=20update=20?= =?UTF-8?q?=E9=87=8D=E6=9E=84=20OssFactory=20=E5=8A=A0=E8=BD=BD=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=20=E6=94=B9=E4=B8=BA=E6=AF=8F=E6=AC=A1=E6=AF=94?= =?UTF-8?q?=E5=AF=B9=E9=85=8D=E7=BD=AE=E5=81=9A=E5=AE=9E=E4=BE=8B=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=20*=20update=20=E4=BC=98=E5=8C=96=20SaTokenDao=20?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=20Bean=20=E6=B3=A8=E5=85=A5=20=E4=BE=BF?= =?UTF-8?q?=E4=BA=8E=E6=89=A9=E5=B1=95=20*=20update=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=20=E9=A1=B9=E7=9B=AE=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=94=B9=E4=B8=BA=E6=87=92=E5=8A=A0=E8=BD=BD=20?= =?UTF-8?q?=E4=B8=8D=E6=8F=90=E4=BE=9B=E7=83=AD=E5=8A=A0=E8=BD=BD=20*=20up?= =?UTF-8?q?date=20=E9=87=8D=E6=9E=84=20=E9=AA=8C=E8=AF=81=E7=A0=81?= =?UTF-8?q?=E5=BC=80=E5=85=B3=E4=BD=BF=E7=94=A8=E9=85=8D=E7=BD=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6(=E7=BB=8F=E8=B0=83=E6=9F=A5=E5=B0=91=E6=9C=89?= =?UTF-8?q?=E5=8A=A8=E6=80=81=E5=BC=80=E5=90=AF=E9=9C=80=E6=B1=82)=20*=20u?= =?UTF-8?q?pdate=20=E4=BC=98=E5=8C=96=20=E5=90=AF=E7=94=A8=20sqlserver=20?= =?UTF-8?q?=E9=AB=98=E7=89=88=E6=9C=AC=E8=AF=AD=E6=B3=95=20=E7=AE=80?= =?UTF-8?q?=E5=8C=96sql=E8=84=9A=E6=9C=AC=E8=AF=AD=E6=B3=95=20*=20update?= =?UTF-8?q?=20=E4=BC=98=E5=8C=96=20DataPermissionHelper=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=20=E5=BC=80=E5=90=AF/=E5=85=B3=E9=97=AD=20=E5=BF=BD?= =?UTF-8?q?=E7=95=A5=E6=95=B0=E6=8D=AE=E6=9D=83=E9=99=90=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=20*=20update=20=E4=BC=98=E5=8C=96=20=E8=BF=9E=E6=8E=A5?= =?UTF-8?q?=E6=B1=A0=E5=A2=9E=E5=8A=A0=20keepaliveTime=20=E6=8E=A2?= =?UTF-8?q?=E6=B4=BB=E5=8F=82=E6=95=B0=20*=20update=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20=E8=B0=83=E6=95=B4=E8=BF=9E=E6=8E=A5=E6=B1=A0=E6=9C=80?= =?UTF-8?q?=E9=95=BF=E7=94=9F=E5=91=BD=E5=91=A8=E6=9C=9F=20=E9=98=B2?= =?UTF-8?q?=E6=AD=A2=E5=87=BA=E7=8E=B0=E8=AD=A6=E5=91=8A=20*=20update=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=20=E4=BB=A3=E7=A0=81=E7=94=9F=E6=88=90?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E6=A8=A1=E6=9D=BF=20=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?=E4=B8=8D=E5=BF=85=E8=A6=81=E7=9A=84=E8=A1=A8=E5=8D=95=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=20*=20add=20=E6=96=B0=E5=A2=9E=20StringUtils=20splitT?= =?UTF-8?q?o=20=E4=B8=8E=20splitList=20=E6=96=B9=E6=B3=95=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E4=B8=9A=E5=8A=A1=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 6 +- .../web/controller/CaptchaController.java | 12 +- .../web/controller/SysLoginController.java | 45 +- .../web/controller/SysRegisterController.java | 2 +- .../com/ruoyi/web/domain/vo/TenantListVo.java | 19 + .../ruoyi/web}/service/SysLoginService.java | 115 +- .../web}/service/SysRegisterService.java | 29 +- .../src/main/resources/application-dev.yml | 4 +- .../src/main/resources/application-prod.yml | 4 +- .../src/main/resources/application.yml | 17 +- .../main/resources/i18n/messages.properties | 5 + .../resources/i18n/messages_en_US.properties | 5 + .../resources/i18n/messages_zh_CN.properties | 5 + ruoyi-common/pom.xml | 1 + ruoyi-common/ruoyi-common-bom/pom.xml | 7 + .../ruoyi/common/core/config/RuoYiConfig.java | 5 - .../common/core/constant/CacheConstants.java | 26 +- .../common/core/constant/CacheNames.java | 5 + .../ruoyi/common/core/constant/Constants.java | 5 + .../common/core/constant/GlobalConstants.java | 39 + .../common/core/constant/TenantConstants.java | 51 + .../common/core/domain/model/LoginBody.java | 6 + .../common/core/domain/model/LoginUser.java | 5 + .../core/domain/model/SmsLoginBody.java | 6 + .../ruoyi/common/core/enums/TenantStatus.java | 30 + .../ruoyi/common/core/utils/ServletUtils.java | 2 +- .../ruoyi/common/core/utils/StreamUtils.java | 2 +- .../ruoyi/common/core/utils/StringUtils.java | 67 +- .../excel/annotation/ExcelDictFormat.java | 4 +- .../ruoyi/common/excel/utils/ExcelUtil.java | 4 +- .../aspectj/RepeatSubmitAspect.java | 4 +- .../ruoyi/common/log/aspect/LogAspect.java | 1 + .../common/log/event/LogininforEvent.java | 5 + .../ruoyi/common/log/event/OperLogEvent.java | 5 + .../mybatis/core/domain/TreeEntity.java | 41 - .../mybatis/core/mapper/BaseMapperPlus.java | 9 +- .../common/mybatis/core/page/PageQuery.java | 4 +- .../MybatisExceptionHandler.java | 2 +- .../handler/PlusDataPermissionHandler.java | 3 +- .../mybatis/helper/DataPermissionHelper.java | 17 + .../com/ruoyi/common/oss/core/OssClient.java | 13 + .../ruoyi/common/oss/factory/OssFactory.java | 42 +- .../ratelimiter/annotation/RateLimiter.java | 4 +- .../common/satoken/config/SaTokenConfig.java | 10 + .../satoken/core/dao/PlusSaTokenDao.java | 2 - .../common/satoken/utils/LoginHelper.java | 57 +- ...ot.autoconfigure.AutoConfiguration.imports | 1 - ruoyi-common/ruoyi-common-security/pom.xml | 6 - .../common/sms/core/TencentSmsTemplate.java | 2 +- ruoyi-common/ruoyi-common-tenant/pom.xml | 37 + .../common/tenant/config/TenantConfig.java | 100 ++ .../common/tenant/core/TenantEntity.java | 21 + .../common/tenant/core/TenantSaTokenDao.java | 114 ++ .../tenant/exception/TenantException.java | 20 + .../tenant/handle/PlusTenantLineHandler.java | 57 + .../tenant/handle/TenantKeyPrefixHandler.java | 58 + .../common/tenant/helper/TenantHelper.java | 112 ++ .../manager/TenantSpringCacheManager.java | 32 + .../tenant/properties/TenantProperties.java | 27 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../ruoyi/common/web/config/FilterConfig.java | 2 +- .../config/properties/CaptchaProperties.java | 2 + .../ruoyi/common/web/filter/XssFilter.java | 2 +- .../demo/controller/TestDemoController.java | 18 +- .../demo/controller/TestTreeController.java | 14 +- .../java/com/ruoyi/demo/domain/TestTree.java | 9 +- .../com/ruoyi/demo/domain/bo/TestTreeBo.java | 14 +- .../generator/constant/GenConstants.java | 15 +- .../com/ruoyi/generator/domain/GenTable.java | 12 +- .../generator/domain/GenTableColumn.java | 2 +- .../com/ruoyi/generator/util/GenUtils.java | 4 +- .../ruoyi/generator/util/VelocityUtils.java | 2 +- .../src/main/resources/vm/java/bo.java.vm | 19 +- .../main/resources/vm/java/controller.java.vm | 14 +- .../src/main/resources/vm/java/domain.java.vm | 33 +- .../main/resources/vm/vue/index-tree.vue.vm | 4 + .../src/main/resources/vm/vue/index.vue.vm | 4 + .../resources/vm/vue/v3/index-tree.vue.vm | 4 + .../src/main/resources/vm/vue/v3/index.vue.vm | 4 + ruoyi-modules/ruoyi-system/pom.xml | 2 +- .../controller/monitor/CacheController.java | 168 -- .../monitor/SysLogininforController.java | 23 +- .../monitor/SysOperlogController.java | 11 +- .../monitor/SysUserOnlineController.java | 11 +- .../controller/system/SysDeptController.java | 10 +- .../controller/system/SysMenuController.java | 41 + .../system/SysOssConfigController.java | 14 +- .../controller/system/SysOssController.java | 12 +- .../system/SysProfileController.java | 4 +- .../controller/system/SysRoleController.java | 22 +- .../system/SysTenantController.java | 168 ++ .../system/SysTenantPackageController.java | 124 ++ .../controller/system/SysUserController.java | 18 +- .../com/ruoyi/system/domain/SysConfig.java | 4 +- .../java/com/ruoyi/system/domain/SysDept.java | 13 +- .../com/ruoyi/system/domain/SysDictData.java | 4 +- .../com/ruoyi/system/domain/SysDictType.java | 4 +- .../ruoyi/system/domain/SysLogininfor.java | 29 +- .../java/com/ruoyi/system/domain/SysMenu.java | 25 +- .../com/ruoyi/system/domain/SysNotice.java | 4 +- .../com/ruoyi/system/domain/SysOperLog.java | 44 +- .../java/com/ruoyi/system/domain/SysOss.java | 4 +- .../com/ruoyi/system/domain/SysOssConfig.java | 4 +- .../java/com/ruoyi/system/domain/SysPost.java | 19 +- .../java/com/ruoyi/system/domain/SysRole.java | 31 +- .../com/ruoyi/system/domain/SysTenant.java | 103 ++ .../ruoyi/system/domain/SysTenantPackage.java | 54 + .../java/com/ruoyi/system/domain/SysUser.java | 6 +- .../com/ruoyi/system/domain/bo/SysDeptBo.java | 11 +- .../system/domain/bo/SysLogininforBo.java | 74 + .../com/ruoyi/system/domain/bo/SysMenuBo.java | 9 +- .../ruoyi/system/domain/bo/SysOperLogBo.java | 116 ++ .../com/ruoyi/system/domain/bo/SysOssBo.java | 1 + .../system/domain/bo/SysOssConfigBo.java | 1 + .../com/ruoyi/system/domain/bo/SysPostBo.java | 1 + .../com/ruoyi/system/domain/bo/SysRoleBo.java | 19 +- .../ruoyi/system/domain/bo/SysTenantBo.java | 111 ++ .../system/domain/bo/SysTenantPackageBo.java | 54 + .../com/ruoyi/system/domain/bo/SysUserBo.java | 2 +- .../com/ruoyi/system/domain/vo/SysDeptVo.java | 2 +- .../system/domain/vo/SysLogininforVo.java | 90 ++ .../ruoyi/system/domain/vo/SysOperLogVo.java | 138 ++ .../com/ruoyi/system/domain/vo/SysRoleVo.java | 8 +- .../system/domain/vo/SysTenantPackageVo.java | 63 + .../ruoyi/system/domain/vo/SysTenantVo.java | 112 ++ .../com/ruoyi/system/domain/vo/SysUserVo.java | 10 +- .../system/mapper/SysLogininforMapper.java | 3 +- .../ruoyi/system/mapper/SysOperLogMapper.java | 3 +- .../ruoyi/system/mapper/SysTenantMapper.java | 14 + .../system/mapper/SysTenantPackageMapper.java | 14 + .../runner/SystemApplicationRunner.java | 13 - .../system/service/ISysConfigService.java | 10 - .../system/service/ISysDictTypeService.java | 10 - .../system/service/ISysLogininforService.java | 11 +- .../ruoyi/system/service/ISysMenuService.java | 8 + .../system/service/ISysOperLogService.java | 13 +- .../system/service/ISysPermissionService.java | 28 + .../service/ISysTenantPackageService.java | 52 + .../system/service/ISysTenantService.java | 72 + .../ruoyi/system/service/ISysUserService.java | 2 +- .../system/service/SysPermissionService.java | 69 - .../service/impl/SysConfigServiceImpl.java | 29 +- .../service/impl/SysDeptServiceImpl.java | 10 +- .../service/impl/SysDictTypeServiceImpl.java | 42 +- .../impl/SysLogininforServiceImpl.java | 19 +- .../service/impl/SysMenuServiceImpl.java | 36 +- .../service/impl/SysOperLogServiceImpl.java | 21 +- .../service/impl/SysOssConfigServiceImpl.java | 47 +- .../service/impl/SysOssServiceImpl.java | 5 +- .../impl/SysPermissionServiceImpl.java | 61 + .../service/impl/SysRoleServiceImpl.java | 18 +- .../service/impl/SysSensitiveServiceImpl.java | 2 +- .../impl/SysTenantPackageServiceImpl.java | 139 ++ .../service/impl/SysTenantServiceImpl.java | 334 ++++ .../service/impl/SysUserServiceImpl.java | 7 +- .../mapper/system/SysTenantMapper.xml | 7 + .../mapper/system/SysTenantPackageMapper.xml | 7 + .../resources/mapper/system/SysUserMapper.xml | 1 + ruoyi-ui/src/api/login.js | 14 +- ruoyi-ui/src/api/system/menu.js | 10 +- ruoyi-ui/src/api/system/tenant.js | 74 + ruoyi-ui/src/api/system/tenantPackage.js | 58 + ruoyi-ui/src/assets/icons/svg/company.svg | 1 + ruoyi-ui/src/layout/components/Navbar.vue | 62 +- ruoyi-ui/src/layout/index.vue | 7 +- ruoyi-ui/src/store/getters.js | 1 + ruoyi-ui/src/store/modules/user.js | 8 +- ruoyi-ui/src/views/login.vue | 31 +- ruoyi-ui/src/views/monitor/cache/list.vue | 241 --- ruoyi-ui/src/views/register.vue | 14 + ruoyi-ui/src/views/system/config/index.vue | 2 +- ruoyi-ui/src/views/system/dict/data.vue | 2 +- ruoyi-ui/src/views/system/dict/index.vue | 2 +- ruoyi-ui/src/views/system/notice/index.vue | 2 +- ruoyi-ui/src/views/system/post/index.vue | 2 +- ruoyi-ui/src/views/system/role/index.vue | 2 +- ruoyi-ui/src/views/system/tenant/index.vue | 419 +++++ .../src/views/system/tenantPackage/index.vue | 388 +++++ ruoyi-ui/src/views/system/user/index.vue | 2 +- script/sql/oracle/oracle_ry_vue_5.X.sql | 378 +++-- script/sql/oracle/oracle_test.sql | 4 +- script/sql/postgres/postgres_ry_vue_5.X.sql | 717 +++++---- script/sql/postgres/postgres_test.sql | 4 +- script/sql/ry_vue_5.X.sql | 278 ++-- script/sql/sqlserver/sqlserver_ry_vue_5.X.sql | 1394 +++++++++++------ script/sql/sqlserver/sqlserver_test.sql | 314 ++-- script/sql/test.sql | 4 +- 187 files changed, 6486 insertions(+), 2372 deletions(-) create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/domain/vo/TenantListVo.java rename {ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system => ruoyi-admin/src/main/java/com/ruoyi/web}/service/SysLoginService.java (63%) rename {ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system => ruoyi-admin/src/main/java/com/ruoyi/web}/service/SysRegisterService.java (69%) create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/GlobalConstants.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TenantConstants.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/TenantStatus.java delete mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/core/domain/TreeEntity.java rename ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/{helper => handler}/MybatisExceptionHandler.java (97%) create mode 100644 ruoyi-common/ruoyi-common-tenant/pom.xml create mode 100644 ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/config/TenantConfig.java create mode 100644 ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/core/TenantEntity.java create mode 100644 ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/core/TenantSaTokenDao.java create mode 100644 ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/exception/TenantException.java create mode 100644 ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/handle/PlusTenantLineHandler.java create mode 100644 ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/handle/TenantKeyPrefixHandler.java create mode 100644 ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/helper/TenantHelper.java create mode 100644 ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/manager/TenantSpringCacheManager.java create mode 100644 ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/properties/TenantProperties.java create mode 100644 ruoyi-common/ruoyi-common-tenant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports delete mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/monitor/CacheController.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysTenantController.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysTenantPackageController.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTenant.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTenantPackage.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysLogininforBo.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysOperLogBo.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysTenantBo.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysTenantPackageBo.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysLogininforVo.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOperLogVo.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysTenantPackageVo.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysTenantVo.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTenantMapper.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTenantPackageMapper.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPermissionService.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTenantPackageService.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTenantService.java delete mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/SysPermissionService.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPermissionServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTenantPackageServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTenantServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysTenantMapper.xml create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysTenantPackageMapper.xml create mode 100644 ruoyi-ui/src/api/system/tenant.js create mode 100644 ruoyi-ui/src/api/system/tenantPackage.js create mode 100644 ruoyi-ui/src/assets/icons/svg/company.svg delete mode 100644 ruoyi-ui/src/views/monitor/cache/list.vue create mode 100644 ruoyi-ui/src/views/system/tenant/index.vue create mode 100644 ruoyi-ui/src/views/system/tenantPackage/index.vue diff --git a/pom.xml b/pom.xml index 8f687cca4..32707d532 100644 --- a/pom.xml +++ b/pom.xml @@ -30,7 +30,7 @@ 5.8.11 4.10.0 3.0.0 - 3.19.1 + 3.19.2 2.2.4 3.6.1 2.14.2 @@ -42,10 +42,10 @@ 1.33 - 1.12.373 + 1.12.400 2.0.23 - 3.1.660 + 3.1.687 3.2.2 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 index 67281ecfe..bfb127a8e 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/CaptchaController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/CaptchaController.java @@ -5,8 +5,8 @@ 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.CacheConstants; 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; @@ -17,8 +17,8 @@ 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.system.service.ISysConfigService; 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; @@ -28,7 +28,6 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; -import jakarta.validation.constraints.NotBlank; import java.time.Duration; import java.util.HashMap; import java.util.Map; @@ -47,7 +46,6 @@ public class CaptchaController { private final CaptchaProperties captchaProperties; private final SmsProperties smsProperties; - private final ISysConfigService configService; /** * 短信验证码 @@ -60,7 +58,7 @@ public class CaptchaController { if (!smsProperties.getEnabled()) { return R.fail("当前系统没有开启短信功能!"); } - String key = CacheConstants.CAPTCHA_CODE_KEY + phonenumber; + String key = GlobalConstants.CAPTCHA_CODE_KEY + phonenumber; String code = RandomUtil.randomNumbers(4); RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION)); // 验证码模板id 自行处理 (查数据库或写死均可) @@ -82,14 +80,14 @@ public class CaptchaController { @GetMapping("/captchaImage") public R getCode() { CaptchaVo captchaVo = new CaptchaVo(); - boolean captchaEnabled = configService.selectCaptchaEnabled(); + boolean captchaEnabled = captchaProperties.getEnable(); if (!captchaEnabled) { captchaVo.setCaptchaEnabled(false); return R.ok(captchaVo); } // 保存验证码信息 String uuid = IdUtil.simpleUUID(); - String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; + String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + uuid; // 生成验证码 CaptchaType captchaType = captchaProperties.getType(); boolean isMath = CaptchaType.MATH == captchaType; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/SysLoginController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/SysLoginController.java index 73e6a245f..f55b5c8e3 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/SysLoginController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/SysLoginController.java @@ -1,19 +1,27 @@ package com.ruoyi.web.controller; import cn.dev33.satoken.annotation.SaIgnore; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.domain.model.LoginBody; import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.domain.model.SmsLoginBody; +import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.satoken.utils.LoginHelper; import com.ruoyi.system.domain.SysMenu; +import com.ruoyi.system.domain.bo.SysTenantBo; import com.ruoyi.system.domain.vo.RouterVo; +import com.ruoyi.system.domain.vo.SysTenantVo; import com.ruoyi.system.domain.vo.SysUserVo; import com.ruoyi.system.service.ISysMenuService; +import com.ruoyi.system.service.ISysTenantService; import com.ruoyi.system.service.ISysUserService; -import com.ruoyi.system.service.SysLoginService; import com.ruoyi.web.domain.vo.LoginVo; +import com.ruoyi.web.domain.vo.TenantListVo; import com.ruoyi.web.domain.vo.UserInfoVo; +import com.ruoyi.web.service.SysLoginService; +import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.constraints.NotBlank; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; @@ -22,6 +30,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; +import java.net.URL; import java.util.List; /** @@ -37,20 +46,23 @@ public class SysLoginController { private final SysLoginService loginService; private final ISysMenuService menuService; private final ISysUserService userService; + private final ISysTenantService tenantService; /** * 登录方法 * - * @param loginBody 登录信息 + * @param body 登录信息 * @return 结果 */ @SaIgnore @PostMapping("/login") - public R login(@Validated @RequestBody LoginBody loginBody) { + public R login(@Validated @RequestBody LoginBody body) { LoginVo loginVo = new LoginVo(); // 生成令牌 - String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), - loginBody.getUuid()); + String token = loginService.login( + body.getTenantId(), + body.getUsername(), body.getPassword(), + body.getCode(), body.getUuid()); loginVo.setToken(token); return R.ok(loginVo); } @@ -58,15 +70,15 @@ public class SysLoginController { /** * 短信登录(示例) * - * @param smsLoginBody 登录信息 + * @param body 登录信息 * @return 结果 */ @SaIgnore @PostMapping("/smsLogin") - public R smsLogin(@Validated @RequestBody SmsLoginBody smsLoginBody) { + public R smsLogin(@Validated @RequestBody SmsLoginBody body) { LoginVo loginVo = new LoginVo(); // 生成令牌 - String token = loginService.smsLogin(smsLoginBody.getPhonenumber(), smsLoginBody.getSmsCode()); + String token = loginService.smsLogin(body.getTenantId(), body.getPhonenumber(), body.getSmsCode()); loginVo.setToken(token); return R.ok(loginVo); } @@ -97,6 +109,23 @@ public class SysLoginController { return R.ok("退出成功"); } + /** + * 登录页面租户下拉框 + * + * @return 租户列表 + */ + @SaIgnore + @GetMapping("/tenant/list") + public R> tenantList(HttpServletRequest request) throws Exception { + List tenantList = tenantService.queryList(new SysTenantBo()); + List voList = BeanUtil.copyToList(tenantList, TenantListVo.class); + // 获取域名 + String host = new URL(request.getRequestURL().toString()).getHost(); + // 根据域名进行筛选 + List list = voList.stream().filter(vo -> StringUtils.equals(vo.getDomain(), host)).toList(); + return R.ok(CollUtil.isNotEmpty(list) ? list : voList); + } + /** * 获取用户信息 * diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/SysRegisterController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/SysRegisterController.java index 46937fb79..21abf93f5 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/SysRegisterController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/SysRegisterController.java @@ -5,7 +5,7 @@ import com.ruoyi.common.web.core.BaseController; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.domain.model.RegisterBody; import com.ruoyi.system.service.ISysConfigService; -import com.ruoyi.system.service.SysRegisterService; +import com.ruoyi.web.service.SysRegisterService; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; 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 new file mode 100644 index 000000000..9f8016bd8 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/domain/vo/TenantListVo.java @@ -0,0 +1,19 @@ +package com.ruoyi.web.domain.vo; + +import lombok.Data; + +/** + * 租户列表 + * + * @author Lion Li + */ +@Data +public class TenantListVo { + + private String tenantId; + + private String companyName; + + private String domain; + +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java b/ruoyi-admin/src/main/java/com/ruoyi/web/service/SysLoginService.java similarity index 63% rename from ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java rename to ruoyi-admin/src/main/java/com/ruoyi/web/service/SysLoginService.java index 4c298ee0b..22795124c 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/service/SysLoginService.java @@ -1,4 +1,4 @@ -package com.ruoyi.system.service; +package com.ruoyi.web.service; import cn.dev33.satoken.exception.NotLoginException; import cn.dev33.satoken.secure.BCrypt; @@ -6,13 +6,14 @@ 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.CacheConstants; import com.ruoyi.common.core.constant.Constants; +import com.ruoyi.common.core.constant.GlobalConstants; 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; @@ -21,9 +22,15 @@ 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 jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -31,6 +38,7 @@ 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; @@ -45,8 +53,9 @@ import java.util.function.Supplier; public class SysLoginService { private final SysUserMapper userMapper; - private final ISysConfigService configService; - private final SysPermissionService permissionService; + private final CaptchaProperties captchaProperties; + private final ISysPermissionService permissionService; + private final ISysTenantService tenantService; @Value("${user.password.maxRetryCount}") private Integer maxRetryCount; @@ -63,36 +72,41 @@ public class SysLoginService { * @param uuid 唯一标识 * @return 结果 */ - public String login(String username, String password, String code, String uuid) { + public String login(String tenantId, String username, String password, String code, String uuid) { HttpServletRequest request = ServletUtils.getRequest(); - boolean captchaEnabled = configService.selectCaptchaEnabled(); + boolean captchaEnabled = captchaProperties.getEnable(); // 验证码开关 if (captchaEnabled) { - validateCaptcha(username, code, uuid, request); + validateCaptcha(tenantId, username, code, uuid, request); } - SysUserVo user = loadUserByUsername(username); - checkLogin(LoginType.PASSWORD, username, () -> !BCrypt.checkpw(password, user.getPassword())); + // 校验租户 + 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(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); + recordLogininfor(loginUser.getTenantId(), username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); recordLoginInfo(user.getUserId()); return StpUtil.getTokenValue(); } - public String smsLogin(String phonenumber, String smsCode) { + public String smsLogin(String tenantId, String phonenumber, String smsCode) { + // 校验租户 + checkTenant(tenantId); // 通过手机号查找用户 - SysUserVo user = loadUserByPhonenumber(phonenumber); + SysUserVo user = loadUserByPhonenumber(tenantId, phonenumber); - checkLogin(LoginType.SMS, user.getUserName(), () -> !validateSmsCode(phonenumber, smsCode)); + checkLogin(LoginType.SMS, tenantId, user.getUserName(), () -> !validateSmsCode(tenantId, phonenumber, smsCode)); // 此处可根据登录用户的数据不同 自行创建 loginUser LoginUser loginUser = buildLoginUser(user); // 生成token LoginHelper.loginByDevice(loginUser, DeviceType.APP); - recordLogininfor(user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); + recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); recordLoginInfo(user.getUserId()); return StpUtil.getTokenValue(); } @@ -104,9 +118,12 @@ public class SysLoginService { // 校验 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()); @@ -114,7 +131,7 @@ public class SysLoginService { // 生成token LoginHelper.loginByDevice(loginUser, DeviceType.XCX); - recordLogininfor(user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); + recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); recordLoginInfo(user.getUserId()); return StpUtil.getTokenValue(); } @@ -126,7 +143,7 @@ public class SysLoginService { try { LoginUser loginUser = LoginHelper.getLoginUser(); StpUtil.logout(); - recordLogininfor(loginUser.getUsername(), Constants.LOGOUT, MessageUtils.message("user.logout.success")); + recordLogininfor(loginUser.getTenantId(), loginUser.getUsername(), Constants.LOGOUT, MessageUtils.message("user.logout.success")); } catch (NotLoginException ignored) { } } @@ -134,13 +151,15 @@ public class SysLoginService { /** * 记录登录信息 * + * @param tenantId 租户ID * @param username 用户名 * @param status 状态 * @param message 消息内容 * @return */ - private void recordLogininfor(String username, String status, String 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); @@ -151,10 +170,10 @@ public class SysLoginService { /** * 校验短信验证码 */ - private boolean validateSmsCode(String phonenumber, String smsCode) { - String code = RedisUtils.getCacheObject(CacheConstants.CAPTCHA_CODE_KEY + phonenumber); + private boolean validateSmsCode(String tenantId, String phonenumber, String smsCode) { + String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + phonenumber); if (StringUtils.isBlank(code)) { - recordLogininfor(phonenumber, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")); + recordLogininfor(tenantId, phonenumber, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")); throw new CaptchaExpireException(); } return code.equals(smsCode); @@ -167,24 +186,25 @@ public class SysLoginService { * @param code 验证码 * @param uuid 唯一标识 */ - public void validateCaptcha(String username, String code, String uuid, HttpServletRequest request) { - String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, ""); + public void validateCaptcha(String tenantId, String username, String code, String uuid, HttpServletRequest request) { + String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, ""); String captcha = RedisUtils.getCacheObject(verifyKey); RedisUtils.deleteObject(verifyKey); if (captcha == null) { - recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")); + recordLogininfor(tenantId, username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")); throw new CaptchaExpireException(); } if (!code.equalsIgnoreCase(captcha)) { - recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")); + recordLogininfor(tenantId, username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")); throw new CaptchaException(); } } - private SysUserVo loadUserByUsername(String username) { + private SysUserVo loadUserByUsername(String tenantId, String username) { SysUser user = userMapper.selectOne(new LambdaQueryWrapper() - .select(SysUser::getUserName, SysUser::getStatus) - .eq(SysUser::getUserName, username)); + .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); @@ -195,10 +215,11 @@ public class SysLoginService { return userMapper.selectUserByUserName(username); } - private SysUserVo loadUserByPhonenumber(String phonenumber) { + private SysUserVo loadUserByPhonenumber(String tenantId, String phonenumber) { SysUser user = userMapper.selectOne(new LambdaQueryWrapper() - .select(SysUser::getPhonenumber, SysUser::getStatus) - .eq(SysUser::getPhonenumber, phonenumber)); + .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); @@ -228,12 +249,13 @@ public class SysLoginService { */ 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(), user.isAdmin())); - loginUser.setRolePermission(permissionService.getRolePermission(user.getUserId(), user.isAdmin())); + loginUser.setMenuPermission(permissionService.getMenuPermission(user.getUserId())); + loginUser.setRolePermission(permissionService.getRolePermission(user.getUserId())); loginUser.setDeptName(ObjectUtil.isNull(user.getDept()) ? "" : user.getDept().getDeptName()); List roles = BeanUtil.copyToList(user.getRoles(), RoleDTO.class); loginUser.setRoles(roles); @@ -257,15 +279,15 @@ public class SysLoginService { /** * 登录校验 */ - private void checkLogin(LoginType loginType, String username, Supplier supplier) { - String errorKey = CacheConstants.PWD_ERR_CNT_KEY + username; + private void checkLogin(LoginType loginType, String tenantId, String username, Supplier 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(username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), maxRetryCount, lockTime)); + recordLogininfor(tenantId, username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), maxRetryCount, lockTime)); throw new UserException(loginType.getRetryLimitExceed(), maxRetryCount, lockTime); } @@ -275,12 +297,12 @@ public class SysLoginService { // 达到规定错误次数 则锁定登录 if (errorNumber.equals(maxRetryCount)) { RedisUtils.setCacheObject(errorKey, errorNumber, Duration.ofMinutes(lockTime)); - recordLogininfor(username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), maxRetryCount, lockTime)); + recordLogininfor(tenantId, username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), maxRetryCount, lockTime)); throw new UserException(loginType.getRetryLimitExceed(), maxRetryCount, lockTime); } else { // 未达到规定错误次数 则递增 RedisUtils.setCacheObject(errorKey, errorNumber); - recordLogininfor(username, loginFail, MessageUtils.message(loginType.getRetryLimitCount(), errorNumber)); + recordLogininfor(tenantId, username, loginFail, MessageUtils.message(loginType.getRetryLimitCount(), errorNumber)); throw new UserException(loginType.getRetryLimitCount(), errorNumber); } } @@ -288,4 +310,23 @@ public class SysLoginService { // 登录成功 清空错误次数 RedisUtils.deleteObject(errorKey); } + + private void checkTenant(String tenantId) { + if (!TenantHelper.isEnable()) { + 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-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/SysRegisterService.java b/ruoyi-admin/src/main/java/com/ruoyi/web/service/SysRegisterService.java similarity index 69% rename from ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/SysRegisterService.java rename to ruoyi-admin/src/main/java/com/ruoyi/web/service/SysRegisterService.java index 5621cb8b7..3f23c21e1 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/SysRegisterService.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/service/SysRegisterService.java @@ -1,8 +1,8 @@ -package com.ruoyi.system.service; +package com.ruoyi.web.service; import cn.dev33.satoken.secure.BCrypt; -import com.ruoyi.common.core.constant.CacheConstants; import com.ruoyi.common.core.constant.Constants; +import com.ruoyi.common.core.constant.GlobalConstants; import com.ruoyi.common.core.constant.UserConstants; import com.ruoyi.common.core.domain.model.RegisterBody; import com.ruoyi.common.core.enums.UserType; @@ -15,7 +15,9 @@ 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 jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -30,22 +32,23 @@ import org.springframework.stereotype.Service; public class SysRegisterService { private final ISysUserService userService; - private final ISysConfigService configService; + private final CaptchaProperties captchaProperties; /** * 注册 */ public void register(RegisterBody registerBody) { HttpServletRequest request = ServletUtils.getRequest(); + String tenantId = registerBody.getTenantId(); String username = registerBody.getUsername(); String password = registerBody.getPassword(); // 校验用户类型是否存在 String userType = UserType.getUserType(registerBody.getUserType()).getUserType(); - boolean captchaEnabled = configService.selectCaptchaEnabled(); + boolean captchaEnabled = captchaProperties.getEnable(); // 验证码开关 if (captchaEnabled) { - validateCaptcha(username, registerBody.getCode(), registerBody.getUuid(), request); + validateCaptcha(tenantId, username, registerBody.getCode(), registerBody.getUuid(), request); } SysUserBo sysUser = new SysUserBo(); sysUser.setUserName(username); @@ -56,11 +59,11 @@ public class SysRegisterService { if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(sysUser))) { throw new UserException("user.register.save.error", username); } - boolean regFlag = userService.registerUser(sysUser); + boolean regFlag = userService.registerUser(sysUser, tenantId); if (!regFlag) { throw new UserException("user.register.error"); } - recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.register.success")); + recordLogininfor(tenantId, username, Constants.REGISTER, MessageUtils.message("user.register.success")); } /** @@ -71,16 +74,16 @@ public class SysRegisterService { * @param uuid 唯一标识 * @return 结果 */ - public void validateCaptcha(String username, String code, String uuid, HttpServletRequest request) { - String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, ""); + public void validateCaptcha(String tenantId, String username, String code, String uuid, HttpServletRequest request) { + String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, ""); String captcha = RedisUtils.getCacheObject(verifyKey); RedisUtils.deleteObject(verifyKey); if (captcha == null) { - recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.jcaptcha.expire")); + recordLogininfor(tenantId, username, Constants.REGISTER, MessageUtils.message("user.jcaptcha.expire")); throw new CaptchaExpireException(); } if (!code.equalsIgnoreCase(captcha)) { - recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.jcaptcha.error")); + recordLogininfor(tenantId, username, Constants.REGISTER, MessageUtils.message("user.jcaptcha.error")); throw new CaptchaException(); } } @@ -88,13 +91,15 @@ public class SysRegisterService { /** * 记录登录信息 * + * @param tenantId 租户ID * @param username 用户名 * @param status 状态 * @param message 消息内容 * @return */ - private void recordLogininfor(String username, String status, String 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); diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml index 081b1d144..92a3640e9 100644 --- a/ruoyi-admin/src/main/resources/application-dev.yml +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -92,9 +92,11 @@ spring: # 空闲连接存活最大时间,默认10分钟 idleTimeout: 600000 # 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟 - maxLifetime: 900000 + maxLifetime: 1800000 # 连接测试query(配置检测连接是否有效) connectionTestQuery: SELECT 1 + # 多久检查一次连接的活性 + keepaliveTime: 30000 --- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉) spring.data: diff --git a/ruoyi-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml index 049ce381a..e760823ad 100644 --- a/ruoyi-admin/src/main/resources/application-prod.yml +++ b/ruoyi-admin/src/main/resources/application-prod.yml @@ -95,9 +95,11 @@ spring: # 空闲连接存活最大时间,默认10分钟 idleTimeout: 600000 # 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟 - maxLifetime: 900000 + maxLifetime: 1800000 # 连接测试query(配置检测连接是否有效) connectionTestQuery: SELECT 1 + # 多久检查一次连接的活性 + keepaliveTime: 30000 --- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉) spring.data: diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index 2f496b023..f18898cfa 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -10,10 +10,9 @@ ruoyi: demoEnabled: true # 获取ip地址开关 addressEnabled: true - # 缓存懒加载 - cacheLazy: false captcha: + enable: true # 页面 <参数设置> 可开启关闭 验证码校验 # 验证码类型 math 数组计算 char 字符验证 type: MATH @@ -136,6 +135,20 @@ security: - /actuator - /actuator/** +# 多租户配置 +tenant: + # 是否开启 + enable: true + # 排除表 + excludes: + - sys_menu + - sys_tenant + - sys_tenant_package + - sys_role_dept + - sys_role_menu + - sys_user_post + - sys_user_role + # MyBatisPlus配置 # https://baomidou.com/config/ mybatis-plus: diff --git a/ruoyi-admin/src/main/resources/i18n/messages.properties b/ruoyi-admin/src/main/resources/i18n/messages.properties index 4ff55f41a..3a5eeac88 100644 --- a/ruoyi-admin/src/main/resources/i18n/messages.properties +++ b/ruoyi-admin/src/main/resources/i18n/messages.properties @@ -43,3 +43,8 @@ sms.code.not.blank=短信验证码不能为空 sms.code.retry.limit.count=短信验证码输入错误{0}次 sms.code.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{1}分钟 xcx.code.not.blank=小程序code不能为空 +##租户 +tenant.number.not.blank=租户编号不能为空 +tenant.not.exists=对不起, 您的租户不存在,请联系管理员 +tenant.blocked=对不起,您的租户已禁用,请联系管理员 +tenant.expired=对不起,您的租户已过期,请联系管理员 diff --git a/ruoyi-admin/src/main/resources/i18n/messages_en_US.properties b/ruoyi-admin/src/main/resources/i18n/messages_en_US.properties index c0faca93a..7568f6805 100644 --- a/ruoyi-admin/src/main/resources/i18n/messages_en_US.properties +++ b/ruoyi-admin/src/main/resources/i18n/messages_en_US.properties @@ -43,3 +43,8 @@ sms.code.not.blank=Sms code cannot be blank sms.code.retry.limit.count=Sms code input error {0} times sms.code.retry.limit.exceed=Sms code input error {0} times, account locked for {1} minutes xcx.code.not.blank=Mini program code cannot be blank +##租户 +tenant.number.not.blank=Tenant number cannot be blank +tenant.not.exists=Sorry, your tenant does not exist. Please contact the administrator +tenant.blocked=Sorry, your tenant is disabled. Please contact the administrator +tenant.expired=Sorry, your tenant has expired. Please contact the administrator. diff --git a/ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties b/ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties index 4ff55f41a..3a5eeac88 100644 --- a/ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties +++ b/ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties @@ -43,3 +43,8 @@ sms.code.not.blank=短信验证码不能为空 sms.code.retry.limit.count=短信验证码输入错误{0}次 sms.code.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{1}分钟 xcx.code.not.blank=小程序code不能为空 +##租户 +tenant.number.not.blank=租户编号不能为空 +tenant.not.exists=对不起, 您的租户不存在,请联系管理员 +tenant.blocked=对不起,您的租户已禁用,请联系管理员 +tenant.expired=对不起,您的租户已过期,请联系管理员 diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index af49f5ffb..4f8e1f104 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -31,6 +31,7 @@ ruoyi-common-sensitive ruoyi-common-json ruoyi-common-encrypt + ruoyi-common-tenant ruoyi-common diff --git a/ruoyi-common/ruoyi-common-bom/pom.xml b/ruoyi-common/ruoyi-common-bom/pom.xml index 72f28e462..3bd6c09a2 100644 --- a/ruoyi-common/ruoyi-common-bom/pom.xml +++ b/ruoyi-common/ruoyi-common-bom/pom.xml @@ -152,6 +152,13 @@ ${revision} + + + com.ruoyi + ruoyi-common-tenant + ${revision} + + 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 index 6185fbcbd..e772a16aa 100644 --- 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 @@ -36,11 +36,6 @@ public class RuoYiConfig { */ private boolean demoEnabled; - /** - * 缓存懒加载 - */ - private boolean cacheLazy; - /** * 获取地址开关 */ 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 index 38a31eea6..c5e8707c5 100644 --- 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 @@ -3,25 +3,15 @@ package com.ruoyi.common.core.constant; /** * 缓存的key 常量 * - * @author ruoyi + * @author Lion Li */ public interface CacheConstants { - /** - * 登录用户 redis key - */ - String LOGIN_TOKEN_KEY = "Authorization:login:token:"; - /** * 在线用户 redis key */ String ONLINE_TOKEN_KEY = "online_tokens:"; - /** - * 验证码 redis key - */ - String CAPTCHA_CODE_KEY = "captcha_codes:"; - /** * 参数管理 cache key */ @@ -32,18 +22,4 @@ public interface CacheConstants { */ String SYS_DICT_KEY = "sys_dict:"; - /** - * 防重提交 redis key - */ - String REPEAT_SUBMIT_KEY = "repeat_submit:"; - - /** - * 限流 redis key - */ - String RATE_LIMIT_KEY = "rate_limit:"; - - /** - * 登录账户密码错误次数 redis key - */ - String PWD_ERR_CNT_KEY = "pwd_err_cnt:"; } 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 index b0d657375..81e92f58d 100644 --- 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 @@ -30,6 +30,11 @@ public interface CacheNames { */ String SYS_DICT = "sys_dict"; + /** + * 租户 + */ + String SYS_TENANT = GlobalConstants.GLOBAL_REDIS_KEY + "sys_tenant#30d"; + /** * 用户账户 */ 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 index 155d0dc4f..9553d1741 100644 --- 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 @@ -72,5 +72,10 @@ public interface Constants { */ 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 new file mode 100644 index 000000000..7fcdad118 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/GlobalConstants.java @@ -0,0 +1,39 @@ +package com.ruoyi.common.core.constant; + +/** + * 全局的key常量 (业务无关的key) + * + * @author Lion Li + */ +public interface GlobalConstants { + + /** + * 全局 redis key (业务无关的key) + */ + 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/TenantConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TenantConstants.java new file mode 100644 index 000000000..30a649b40 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TenantConstants.java @@ -0,0 +1,51 @@ +package com.ruoyi.common.core.constant; + +/** + * 租户常量信息 + * + * @author Lion Li + */ +public interface TenantConstants { + + /** + * 租户正常状态 + */ + String NORMAL = "0"; + + /** + * 租户封禁状态 + */ + String DISABLE = "1"; + + /** + * 校验返回结果码 + */ + String PASS = "0"; + String NOT_PASS = "1"; + + /** + * 超级管理员ID + */ + 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/domain/model/LoginBody.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java index eab65812f..153c02fd6 100644 --- 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 @@ -15,6 +15,12 @@ import jakarta.validation.constraints.NotBlank; @Data public class LoginBody { + /** + * 租户ID + */ + @NotBlank(message = "{tenant.number.not.blank}") + private String tenantId; + /** * 用户名 */ 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 index 7db0464de..47126f2b5 100644 --- 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 @@ -22,6 +22,11 @@ public class LoginUser implements Serializable { @Serial private static final long serialVersionUID = 1L; + /** + * 租户ID + */ + private String tenantId; + /** * 用户ID */ 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 index 5bf95c471..3b25fce00 100644 --- 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 @@ -13,6 +13,12 @@ import jakarta.validation.constraints.NotBlank; @Data public class SmsLoginBody { + /** + * 租户ID + */ + @NotBlank(message = "{tenant.number.not.blank}") + private String tenantId; + /** * 用户名 */ 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 new file mode 100644 index 000000000..166804be0 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/TenantStatus.java @@ -0,0 +1,30 @@ +package com.ruoyi.common.core.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 用户状态 + * + * @author LionLi + */ +@Getter +@AllArgsConstructor +public enum TenantStatus { + /** + * 正常 + */ + OK("0", "正常"), + /** + * 停用 + */ + 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/utils/ServletUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ServletUtils.java index 4cff1d573..99bb1da72 100644 --- 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 @@ -92,7 +92,7 @@ public class ServletUtils extends JakartaServletUtil { public static Map getParamMap(ServletRequest request) { Map params = new HashMap<>(); for (Map.Entry entry : getParams(request).entrySet()) { - params.put(entry.getKey(), StringUtils.join(entry.getValue(), ",")); + params.put(entry.getKey(), StringUtils.join(entry.getValue(), StringUtils.SEPARATOR)); } return params; } 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 index c8643157b..28fce3576 100644 --- 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 @@ -42,7 +42,7 @@ public class StreamUtils { * @return 拼接后的list */ public static String join(Collection collection, Function function) { - return join(collection, function, ","); + return join(collection, function, StringUtils.SEPARATOR); } /** 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 index cf19a026a..5b1c8cab7 100644 --- 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 @@ -1,16 +1,16 @@ 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.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; /** * 字符串工具类 @@ -20,6 +20,8 @@ import java.util.Set; @NoArgsConstructor(access = AccessLevel.PRIVATE) public class StringUtils extends org.apache.commons.lang3.StringUtils { + public static final String SEPARATOR = ","; + /** * 获取参数不为空值 * @@ -233,7 +235,7 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils { /** * 数字左边补齐0,使之达到指定长度。注意,如果数字转换为字符串后,长度大于size,则只保留 最后size个字符。 * - * @param num 数字对象 + * @param num 数字对象 * @param size 字符串指定长度 * @return 返回数字的字符串格式,该字符串为指定长度。 */ @@ -244,9 +246,9 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils { /** * 字符串左补齐。如果原始字符串s长度大于size,则只保留最后size个字符。 * - * @param s 原始字符串 + * @param s 原始字符串 * @param size 字符串指定长度 - * @param c 用于补齐的字符 + * @param c 用于补齐的字符 * @return 返回指定长度的字符串,由原字符串左补齐或截取得到。 */ public static String padl(final String s, final int size, final char c) { @@ -265,4 +267,55 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils { return sb.toString(); } + /** + * 切分字符串(分隔符默认逗号) + * + * @param str 被切分的字符串 + * @return 分割后的数据列表 + */ + public static List splitList(String str) { + return splitTo(str, Convert::toStr); + } + + /** + * 切分字符串 + * + * @param str 被切分的字符串 + * @param separator 分隔符 + * @return 分割后的数据列表 + */ + public static List splitList(String str, String separator) { + return splitTo(str, separator, Convert::toStr); + } + + /** + * 切分字符串自定义转换(分隔符默认逗号) + * + * @param str 被切分的字符串 + * @param mapper 自定义转换 + * @return 分割后的数据列表 + */ + public static List splitTo(String str, Function mapper) { + return splitTo(str, SEPARATOR, mapper); + } + + /** + * 切分字符串自定义转换 + * + * @param str 被切分的字符串 + * @param separator 分隔符 + * @param mapper 自定义转换 + * @return 分割后的数据列表 + */ + public static List splitTo(String str, String separator, Function 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-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 index a9671fb62..162dc7965 100644 --- 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 @@ -1,5 +1,7 @@ package com.ruoyi.common.excel.annotation; +import com.ruoyi.common.core.utils.StringUtils; + import java.lang.annotation.*; /** @@ -25,6 +27,6 @@ public @interface ExcelDictFormat { /** * 分隔符,读取字符串组内容 */ - String separator() default ","; + String separator() default StringUtils.SEPARATOR; } 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 index c67cff69a..2e7770126 100644 --- 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 @@ -269,7 +269,7 @@ public class ExcelUtil { */ public static String convertByExp(String propertyValue, String converterExp, String separator) { StringBuilder propertyString = new StringBuilder(); - String[] convertSource = converterExp.split(","); + String[] convertSource = converterExp.split(StringUtils.SEPARATOR); for (String item : convertSource) { String[] itemArray = item.split("="); if (StringUtils.containsAny(propertyValue, separator)) { @@ -298,7 +298,7 @@ public class ExcelUtil { */ public static String reverseByExp(String propertyValue, String converterExp, String separator) { StringBuilder propertyString = new StringBuilder(); - String[] convertSource = converterExp.split(","); + String[] convertSource = converterExp.split(StringUtils.SEPARATOR); for (String item : convertSource) { String[] itemArray = item.split("="); if (StringUtils.containsAny(propertyValue, separator)) { 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 index 1d8bcf44e..37824d5d7 100644 --- 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 @@ -3,7 +3,7 @@ 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.CacheConstants; +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; @@ -57,7 +57,7 @@ public class RepeatSubmitAspect { submitKey = SecureUtil.md5(submitKey + ":" + nowParams); // 唯一标识(指定key + url + 消息头) - String cacheRepeatKey = CacheConstants.REPEAT_SUBMIT_KEY + url + submitKey; + String cacheRepeatKey = GlobalConstants.REPEAT_SUBMIT_KEY + url + submitKey; String key = RedisUtils.getCacheObject(cacheRepeatKey); if (key == null) { RedisUtils.setCacheObject(cacheRepeatKey, "", Duration.ofMillis(interval)); 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 index ca8a568d7..d85d15219 100644 --- 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 @@ -67,6 +67,7 @@ public class LogAspect { // *========数据库日志=========*// OperLogEvent operLog = new OperLogEvent(); + operLog.setTenantId(LoginHelper.getTenantId()); operLog.setStatus(BusinessStatus.SUCCESS.ordinal()); // 请求的地址 String ip = ServletUtils.getClientIP(); 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 index e52e10292..785f5899d 100644 --- 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 @@ -19,6 +19,11 @@ public class LogininforEvent implements Serializable { @Serial private static final long serialVersionUID = 1L; + /** + * 租户ID + */ + private String tenantId; + /** * 用户账号 */ 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 index be07dd0d4..ecb4b7c18 100644 --- 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 @@ -23,6 +23,11 @@ public class OperLogEvent implements Serializable { */ private Long operId; + /** + * 租户ID + */ + private String tenantId; + /** * 操作模块 */ diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/core/domain/TreeEntity.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/core/domain/TreeEntity.java deleted file mode 100644 index a238083b5..000000000 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/core/domain/TreeEntity.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.ruoyi.common.mybatis.core.domain; - -import com.baomidou.mybatisplus.annotation.TableField; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serial; -import java.util.ArrayList; -import java.util.List; - -/** - * Tree基类 - * - * @author Lion Li - */ - -@Data -@EqualsAndHashCode(callSuper = true) -public class TreeEntity extends BaseEntity { - - @Serial - private static final long serialVersionUID = 1L; - - /** - * 父菜单名称 - */ - @TableField(exist = false) - private String parentName; - - /** - * 父菜单ID - */ - private Long parentId; - - /** - * 子部门 - */ - @TableField(exist = false) - private List children = new ArrayList<>(); - -} 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 index ee1bc5822..68a3509a8 100644 --- 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 @@ -6,7 +6,7 @@ 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.*; +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.BeanCopyUtils; @@ -17,6 +17,9 @@ 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 接口, 实现 自定义扩展 @@ -193,4 +196,8 @@ public interface BaseMapperPlus extends BaseMapper { return (P) voPage; } + default List selectObjs(Wrapper wrapper, Function 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 index 30a3e2dc5..d4c2432b9 100644 --- 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 @@ -89,8 +89,8 @@ public class PageQuery implements Serializable { // 兼容前端排序类型 isAsc = StringUtils.replaceEach(isAsc, new String[]{"ascending", "descending"}, new String[]{"asc", "desc"}); - String[] orderByArr = orderBy.split(","); - String[] isAscArr = isAsc.split(","); + String[] orderByArr = orderBy.split(StringUtils.SEPARATOR); + String[] isAscArr = isAsc.split(StringUtils.SEPARATOR); if (isAscArr.length != 1 && isAscArr.length != orderByArr.length) { throw new ServiceException("排序参数有误"); } diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/helper/MybatisExceptionHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/handler/MybatisExceptionHandler.java similarity index 97% rename from ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/helper/MybatisExceptionHandler.java rename to ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/handler/MybatisExceptionHandler.java index 532cd7984..12e1d0c37 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/helper/MybatisExceptionHandler.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/com/ruoyi/common/mybatis/handler/MybatisExceptionHandler.java @@ -1,4 +1,4 @@ -package com.ruoyi.common.mybatis.helper; +package com.ruoyi.common.mybatis.handler; import com.ruoyi.common.core.domain.R; import lombok.extern.slf4j.Slf4j; 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 index 42e238a10..740f932f1 100644 --- 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 @@ -35,7 +35,6 @@ import java.lang.reflect.Method; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; -import java.util.stream.Collectors; /** * 数据权限过滤 @@ -79,7 +78,7 @@ public class PlusDataPermissionHandler { DataPermissionHelper.setVariable("user", currentUser); } // 如果是超级管理员,则不过滤数据 - if (LoginHelper.isAdmin()) { + if (LoginHelper.isSuperAdmin()) { return where; } String dataFilterSql = buildDataFilter(dataColumns, isSelect); 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 index 209416628..8423c1cfa 100644 --- 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 @@ -3,6 +3,8 @@ 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; @@ -44,4 +46,19 @@ public class DataPermissionHelper { } 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-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 index 7a72a5dda..924efc19b 100644 --- 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 @@ -183,6 +183,12 @@ public class OssClient { return configKey; } + /** + * 获取私有URL链接 + * + * @param objectKey 对象KEY + * @param second 授权时间 + */ public String getPrivateUrl(String objectKey, Integer second) { GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(properties.getBucketName(), objectKey) @@ -192,6 +198,13 @@ public class OssClient { return url.toString(); } + /** + * 检查配置是否相同 + */ + public boolean checkPropertiesSame(OssProperties properties) { + return this.properties.equals(properties); + } + /** * 获取当前桶权限类型 * 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 index 885c7be2e..82467efca 100644 --- 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 @@ -24,21 +24,6 @@ public class OssFactory { private static final Map CLIENT_CACHE = new ConcurrentHashMap<>(); - /** - * 初始化工厂 - */ - public static void init() { - log.info("初始化OSS工厂"); - RedisUtils.subscribe(OssConstant.DEFAULT_CONFIG_KEY, String.class, configKey -> { - OssClient client = getClient(configKey); - // 未初始化不处理 - if (client != null) { - refresh(configKey); - log.info("订阅刷新OSS配置 => " + configKey); - } - }); - } - /** * 获取默认实例 */ @@ -55,25 +40,24 @@ public class OssFactory { * 根据类型获取实例 */ public static OssClient instance(String configKey) { - OssClient client = getClient(configKey); - if (client == null) { - refresh(configKey); - return getClient(configKey); - } - return client; - } - - private static void refresh(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); - CLIENT_CACHE.put(configKey, new OssClient(configKey, properties)); - } - - private static OssClient getClient(String configKey) { - return CLIENT_CACHE.get(configKey); + 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-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 index b5bd284f1..9fe9b0aa0 100644 --- 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 @@ -1,6 +1,6 @@ package com.ruoyi.common.ratelimiter.annotation; -import com.ruoyi.common.core.constant.CacheConstants; +import com.ruoyi.common.core.constant.GlobalConstants; import com.ruoyi.common.ratelimiter.enums.LimitType; import java.lang.annotation.*; @@ -17,7 +17,7 @@ public @interface RateLimiter { /** * 限流key */ - String key() default CacheConstants.RATE_LIMIT_KEY; + String key() default GlobalConstants.RATE_LIMIT_KEY; /** * 限流时间,单位秒 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 index f4fe28bc2..609e3ec4b 100644 --- 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 @@ -1,8 +1,10 @@ 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; @@ -30,4 +32,12 @@ public class SaTokenConfig implements WebMvcConfigurer { return new SaPermissionImpl(); } + /** + * 自定义dao层存储 + */ + @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 index 52dd9036e..aafa457cf 100644 --- 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 @@ -3,7 +3,6 @@ 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 org.springframework.stereotype.Component; import java.time.Duration; import java.util.ArrayList; @@ -15,7 +14,6 @@ import java.util.List; * * @author Lion Li */ -@Component public class PlusSaTokenDao implements SaTokenDao { /** 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 index f7fefa3c5..3bff1f268 100644 --- 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 @@ -1,8 +1,11 @@ package com.ruoyi.common.satoken.utils; import cn.dev33.satoken.context.SaHolder; +import cn.dev33.satoken.stp.SaLoginModel; import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONObject; +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; @@ -12,6 +15,8 @@ import com.ruoyi.common.core.utils.StringUtils; import lombok.AccessLevel; import lombok.NoArgsConstructor; +import java.util.Set; + /** * 登录鉴权助手 *

@@ -37,8 +42,7 @@ public class LoginHelper { */ public static void login(LoginUser loginUser) { SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser); - StpUtil.login(loginUser.getLoginId()); - setLoginUser(loginUser); + StpUtil.login(loginUser.getLoginId(), new SaLoginModel().setExtra(LOGIN_USER_KEY, loginUser)); } /** @@ -49,15 +53,9 @@ public class LoginHelper { */ public static void loginByDevice(LoginUser loginUser, DeviceType deviceType) { SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser); - StpUtil.login(loginUser.getLoginId(), deviceType.getDevice()); - setLoginUser(loginUser); - } - - /** - * 设置用户数据(多级缓存) - */ - public static void setLoginUser(LoginUser loginUser) { - StpUtil.getTokenSession().set(LOGIN_USER_KEY, loginUser); + StpUtil.login(loginUser.getLoginId(), new SaLoginModel() + .setDevice(deviceType.getDevice()) + .setExtra(LOGIN_USER_KEY, loginUser)); } /** @@ -68,7 +66,7 @@ public class LoginHelper { if (loginUser != null) { return loginUser; } - loginUser = (LoginUser) StpUtil.getTokenSession().get(LOGIN_USER_KEY); + loginUser = ((JSONObject) StpUtil.getExtra(LOGIN_USER_KEY)).toBean(LoginUser.class); SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser); return loginUser; } @@ -96,6 +94,19 @@ public class LoginHelper { return loginUser.getUserId(); } + /** + * 获取租户ID + */ + public static String getTenantId() { + LoginUser loginUser; + try { + loginUser = getLoginUser(); + } catch (Exception e) { + return null; + } + return loginUser.getTenantId(); + } + /** * 获取部门ID */ @@ -119,17 +130,31 @@ public class LoginHelper { } /** - * 是否为管理员 + * 是否为超级管理员 * * @param userId 用户ID * @return 结果 */ - public static boolean isAdmin(Long userId) { + public static boolean isSuperAdmin(Long userId) { return UserConstants.SUPER_ADMIN_ID.equals(userId); } - public static boolean isAdmin() { - return isAdmin(getUserId()); + public static boolean isSuperAdmin() { + return isSuperAdmin(getUserId()); + } + + /** + * 是否为超级管理员 + * + * @param rolePermission 角色权限标识组 + * @return 结果 + */ + public static boolean isTenantAdmin(Set 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 78e5b7e01..d358acb71 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,2 +1 @@ -com.ruoyi.common.satoken.core.dao.PlusSaTokenDao com.ruoyi.common.satoken.config.SaTokenConfig diff --git a/ruoyi-common/ruoyi-common-security/pom.xml b/ruoyi-common/ruoyi-common-security/pom.xml index eaa3258c9..1cc554bbe 100644 --- a/ruoyi-common/ruoyi-common-security/pom.xml +++ b/ruoyi-common/ruoyi-common-security/pom.xml @@ -22,12 +22,6 @@ ruoyi-common-satoken - - - cn.dev33 - sa-token-spring-boot3-starter - ${satoken.version} - 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 index a7be95ab2..8dbd1ad3c 100644 --- 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 @@ -53,7 +53,7 @@ public class TencentSmsTemplate implements SmsTemplate { throw new SmsException("模板ID不能为空"); } SendSmsRequest req = new SendSmsRequest(); - Set set = Arrays.stream(phones.split(",")).map(p -> "+86" + p).collect(Collectors.toSet()); + Set 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)); diff --git a/ruoyi-common/ruoyi-common-tenant/pom.xml b/ruoyi-common/ruoyi-common-tenant/pom.xml new file mode 100644 index 000000000..5eeb86a07 --- /dev/null +++ b/ruoyi-common/ruoyi-common-tenant/pom.xml @@ -0,0 +1,37 @@ + + + + com.ruoyi + ruoyi-common + ${revision} + ../pom.xml + + 4.0.0 + + ruoyi-common-tenant + + + ruoyi-common-tenant 租户模块 + + + + + com.ruoyi + ruoyi-common-mybatis + + + + com.ruoyi + ruoyi-common-redis + + + + com.alibaba + transmittable-thread-local + + + + + 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 new file mode 100644 index 000000000..373e77c64 --- /dev/null +++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/config/TenantConfig.java @@ -0,0 +1,100 @@ +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 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(); + } + + /** + * 多租户鉴权dao实现 + */ + @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 new file mode 100644 index 000000000..2864ccd74 --- /dev/null +++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/core/TenantEntity.java @@ -0,0 +1,21 @@ +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 new file mode 100644 index 000000000..db9c0258c --- /dev/null +++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/core/TenantSaTokenDao.java @@ -0,0 +1,114 @@ +package com.ruoyi.common.tenant.core; + +import com.ruoyi.common.core.constant.GlobalConstants; +import com.ruoyi.common.satoken.core.dao.PlusSaTokenDao; + +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); + } + + /** + * 修修改指定key-value键值对 (过期时间不变) + */ + @Override + public void update(String key, String value) { + super.update(GlobalConstants.GLOBAL_REDIS_KEY + key, value); + } + + /** + * 删除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) { + super.updateTimeout(GlobalConstants.GLOBAL_REDIS_KEY + key, 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) { + super.updateObject(GlobalConstants.GLOBAL_REDIS_KEY + key, object); + } + + /** + * 删除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) { + super.updateObjectTimeout(GlobalConstants.GLOBAL_REDIS_KEY + key, timeout); + } + + + /** + * 搜索数据 + */ + @Override + public List 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 new file mode 100644 index 000000000..371bc12bc --- /dev/null +++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/exception/TenantException.java @@ -0,0 +1,20 @@ +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 new file mode 100644 index 000000000..0133adbf6 --- /dev/null +++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/handle/PlusTenantLineHandler.java @@ -0,0 +1,57 @@ +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.LongValue; +import net.sf.jsqlparser.expression.NullValue; + +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 LongValue(dynamicTenantId); + } + // 返回固定租户 + return new LongValue(tenantId); + } + + @Override + public boolean ignoreTable(String tableName) { + String tenantId = LoginHelper.getTenantId(); + // 判断是否有租户 + if (StringUtils.isNotBlank(tenantId)) { + // 不需要过滤租户的表 + List 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 new file mode 100644 index 000000000..729702da9 --- /dev/null +++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/handle/TenantKeyPrefixHandler.java @@ -0,0 +1,58 @@ +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; + +/** + * 多租户redis缓存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 new file mode 100644 index 000000000..f9815be9d --- /dev/null +++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/helper/TenantHelper.java @@ -0,0 +1,112 @@ +package com.ruoyi.common.tenant.helper; + +import cn.dev33.satoken.context.SaHolder; +import cn.dev33.satoken.spring.SpringMVCUtil; +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 com.ruoyi.common.tenant.properties.TenantProperties; +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 TenantProperties PROPERTIES = SpringUtils.getBean(TenantProperties.class); + + private static final String DYNAMIC_TENANT_KEY = GlobalConstants.GLOBAL_REDIS_KEY + "dynamicTenant"; + + private static final ThreadLocal TEMP_DYNAMIC_TENANT = new TransmittableThreadLocal<>(); + + /** + * 租户功能是否启用 + */ + public static boolean isEnable() { + return PROPERTIES.getEnable(); + } + + /** + * 开启忽略租户(开启后需手动调用 {@link #disableIgnore()} 关闭) + */ + public static void enableIgnore() { + InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().tenantLine(true).build()); + } + + /** + * 关闭忽略租户 + */ + public static void disableIgnore() { + InterceptorIgnoreHelper.clearIgnoreStrategy(); + } + + /** + * 设置动态租户(一直有效 需要手动清理) + *

+ * 如果为非web环境 那么只在当前线程内生效 + */ + public static void setDynamic(String tenantId) { + if (!SpringMVCUtil.isWeb()) { + TEMP_DYNAMIC_TENANT.set(tenantId); + return; + } + String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getTenantId(); + RedisUtils.setCacheObject(cacheKey, tenantId); + SaHolder.getStorage().set(cacheKey, tenantId); + } + + /** + * 获取动态租户(一直有效 需要手动清理) + *

+ * 如果为非web环境 那么只在当前线程内生效 + */ + public static String getDynamic() { + if (!SpringMVCUtil.isWeb()) { + return TEMP_DYNAMIC_TENANT.get(); + } + String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getTenantId(); + 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.getTenantId(); + 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 new file mode 100644 index 000000000..83402b76f --- /dev/null +++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/manager/TenantSpringCacheManager.java @@ -0,0 +1,32 @@ +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 new file mode 100644 index 000000000..473ea77bf --- /dev/null +++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/com/ruoyi/common/tenant/properties/TenantProperties.java @@ -0,0 +1,27 @@ +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 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 new file mode 100644 index 000000000..8f39d11f1 --- /dev/null +++ b/ruoyi-common/ruoyi-common-tenant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +com.ruoyi.common.tenant.config.TenantConfig 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 index 098ad815f..7444f733b 100644 --- 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 @@ -30,7 +30,7 @@ public class FilterConfig { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setDispatcherTypes(DispatcherType.REQUEST); registration.setFilter(new XssFilter()); - registration.addUrlPatterns(StringUtils.split(xssProperties.getUrlPatterns(), ",")); + registration.addUrlPatterns(StringUtils.split(xssProperties.getUrlPatterns(), StringUtils.SEPARATOR)); registration.setName("xssFilter"); registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE); Map initParameters = new HashMap<>(); 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 index 9bebbd9fe..e4b8e1589 100644 --- 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 @@ -14,6 +14,8 @@ import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix = "captcha") public class CaptchaProperties { + private Boolean enable; + /** * 验证码类型 */ 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 index a11660f6a..5ae7e7d7b 100644 --- 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 @@ -25,7 +25,7 @@ public class XssFilter implements Filter { public void init(FilterConfig filterConfig) throws ServletException { String tempExcludes = filterConfig.getInitParameter("excludes"); if (StringUtils.isNotEmpty(tempExcludes)) { - String[] url = tempExcludes.split(","); + String[] url = tempExcludes.split(StringUtils.SEPARATOR); for (int i = 0; url != null && i < url.length; i++) { excludes.add(url[i]); } 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 index d16fe9d71..3747b61b3 100644 --- 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 @@ -45,7 +45,7 @@ import java.util.concurrent.TimeUnit; @RequestMapping("/demo/demo") public class TestDemoController extends BaseController { - private final ITestDemoService iTestDemoService; + private final ITestDemoService testDemoService; /** * 查询测试单表列表 @@ -53,7 +53,7 @@ public class TestDemoController extends BaseController { @SaCheckPermission("demo:demo:list") @GetMapping("/list") public TableDataInfo list(@Validated(QueryGroup.class) TestDemoBo bo, PageQuery pageQuery) { - return iTestDemoService.queryPageList(bo, pageQuery); + return testDemoService.queryPageList(bo, pageQuery); } /** @@ -62,7 +62,7 @@ public class TestDemoController extends BaseController { @SaCheckPermission("demo:demo:list") @GetMapping("/page") public TableDataInfo page(@Validated(QueryGroup.class) TestDemoBo bo, PageQuery pageQuery) { - return iTestDemoService.customPageList(bo, pageQuery); + return testDemoService.customPageList(bo, pageQuery); } /** @@ -77,7 +77,7 @@ public class TestDemoController extends BaseController { ExcelResult excelResult = ExcelUtil.importExcel(file.getInputStream(), TestDemoImportVo.class, true); List volist = excelResult.getList(); List list = BeanUtil.copyToList(volist, TestDemo.class); - iTestDemoService.saveBatch(list); + testDemoService.saveBatch(list); return R.ok(excelResult.getAnalysis()); } @@ -88,7 +88,7 @@ public class TestDemoController extends BaseController { @Log(title = "测试单表", businessType = BusinessType.EXPORT) @PostMapping("/export") public void export(@Validated TestDemoBo bo, HttpServletResponse response) { - List list = iTestDemoService.queryList(bo); + List list = testDemoService.queryList(bo); // 测试雪花id导出 // for (TestDemoVo vo : list) { // vo.setId(1234567891234567893L); @@ -105,7 +105,7 @@ public class TestDemoController extends BaseController { @GetMapping("/{id}") public R getInfo(@NotNull(message = "主键不能为空") @PathVariable("id") Long id) { - return R.ok(iTestDemoService.queryById(id)); + return R.ok(testDemoService.queryById(id)); } /** @@ -119,7 +119,7 @@ public class TestDemoController extends BaseController { // 使用校验工具对标 @Validated(AddGroup.class) 注解 // 用于在非 Controller 的地方校验对象 ValidatorUtils.validate(bo, AddGroup.class); - return toAjax(iTestDemoService.insertByBo(bo)); + return toAjax(testDemoService.insertByBo(bo)); } /** @@ -130,7 +130,7 @@ public class TestDemoController extends BaseController { @RepeatSubmit @PutMapping() public R edit(@Validated(EditGroup.class) @RequestBody TestDemoBo bo) { - return toAjax(iTestDemoService.updateByBo(bo)); + return toAjax(testDemoService.updateByBo(bo)); } /** @@ -143,6 +143,6 @@ public class TestDemoController extends BaseController { @DeleteMapping("/{ids}") public R remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) { - return toAjax(iTestDemoService.deleteWithValidByIds(Arrays.asList(ids), true)); + return toAjax(testDemoService.deleteWithValidByIds(Arrays.asList(ids), true)); } } 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 index ec8821c20..51a680d2b 100644 --- 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 @@ -35,7 +35,7 @@ import java.util.List; @RequestMapping("/demo/tree") public class TestTreeController extends BaseController { - private final ITestTreeService iTestTreeService; + private final ITestTreeService testTreeService; /** * 查询测试树表列表 @@ -43,7 +43,7 @@ public class TestTreeController extends BaseController { @SaCheckPermission("demo:tree:list") @GetMapping("/list") public R> list(@Validated(QueryGroup.class) TestTreeBo bo) { - List list = iTestTreeService.queryList(bo); + List list = testTreeService.queryList(bo); return R.ok(list); } @@ -54,7 +54,7 @@ public class TestTreeController extends BaseController { @Log(title = "测试树表", businessType = BusinessType.EXPORT) @GetMapping("/export") public void export(@Validated TestTreeBo bo, HttpServletResponse response) { - List list = iTestTreeService.queryList(bo); + List list = testTreeService.queryList(bo); ExcelUtil.exportExcel(list, "测试树表", TestTreeVo.class, response); } @@ -67,7 +67,7 @@ public class TestTreeController extends BaseController { @GetMapping("/{id}") public R getInfo(@NotNull(message = "主键不能为空") @PathVariable("id") Long id) { - return R.ok(iTestTreeService.queryById(id)); + return R.ok(testTreeService.queryById(id)); } /** @@ -78,7 +78,7 @@ public class TestTreeController extends BaseController { @RepeatSubmit @PostMapping() public R add(@Validated(AddGroup.class) @RequestBody TestTreeBo bo) { - return toAjax(iTestTreeService.insertByBo(bo)); + return toAjax(testTreeService.insertByBo(bo)); } /** @@ -89,7 +89,7 @@ public class TestTreeController extends BaseController { @RepeatSubmit @PutMapping() public R edit(@Validated(EditGroup.class) @RequestBody TestTreeBo bo) { - return toAjax(iTestTreeService.updateByBo(bo)); + return toAjax(testTreeService.updateByBo(bo)); } /** @@ -102,6 +102,6 @@ public class TestTreeController extends BaseController { @DeleteMapping("/{ids}") public R remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) { - return toAjax(iTestTreeService.deleteWithValidByIds(Arrays.asList(ids), true)); + return toAjax(testTreeService.deleteWithValidByIds(Arrays.asList(ids), true)); } } 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 index 056700254..14f135571 100644 --- 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 @@ -4,7 +4,7 @@ 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.mybatis.core.domain.TreeEntity; +import com.ruoyi.common.mybatis.core.domain.BaseEntity; import lombok.Data; import lombok.EqualsAndHashCode; @@ -19,7 +19,7 @@ import java.io.Serial; @Data @EqualsAndHashCode(callSuper = true) @TableName("test_tree") -public class TestTree extends TreeEntity { +public class TestTree extends BaseEntity { @Serial private static final long serialVersionUID = 1L; @@ -30,6 +30,11 @@ public class TestTree extends TreeEntity { @TableId(value = "id") private Long id; + /** + * 父ID + */ + private Long parentId; + /** * 部门id */ 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 index 7e6daab12..8251b5b64 100644 --- 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 @@ -2,12 +2,11 @@ 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.TreeEntity; -import lombok.Data; -import lombok.EqualsAndHashCode; - +import com.ruoyi.common.mybatis.core.domain.BaseEntity; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; +import lombok.Data; +import lombok.EqualsAndHashCode; /** * 测试树表业务对象 test_tree @@ -18,7 +17,7 @@ import jakarta.validation.constraints.NotNull; @Data @EqualsAndHashCode(callSuper = true) -public class TestTreeBo extends TreeEntity { +public class TestTreeBo extends BaseEntity { /** * 主键 @@ -26,6 +25,11 @@ public class TestTreeBo extends TreeEntity { @NotNull(message = "主键不能为空", groups = {EditGroup.class}) private Long id; + /** + * 父ID + */ + private Long parentId; + /** * 部门id */ 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 index f2c59c9e5..eb0d12f09 100644 --- 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 @@ -69,35 +69,30 @@ public interface GenConstants { * BO对象 不需要添加字段 */ String[] COLUMNNAME_NOT_ADD = {"create_dept", "create_by", "create_time", "del_flag", "update_by", - "update_time", "version"}; + "update_time", "version", "tenant_id"}; /** * BO对象 不需要编辑字段 */ String[] COLUMNNAME_NOT_EDIT = {"create_dept", "create_by", "create_time", "del_flag", "update_by", - "update_time", "version"}; + "update_time", "version", "tenant_id"}; /** * VO对象 不需要返回字段 */ String[] COLUMNNAME_NOT_LIST = {"create_dept", "create_by", "create_time", "del_flag", "update_by", - "update_time", "version"}; + "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"}; + "update_time", "remark", "version", "tenant_id"}; /** * Entity基类字段 */ - String[] BASE_ENTITY = {"createDept", "createBy", "createTime", "updateBy", "updateTime"}; - - /** - * Tree基类字段 - */ - String[] TREE_ENTITY = {"parentName", "parentId", "children"}; + String[] BASE_ENTITY = {"createDept", "createBy", "createTime", "updateBy", "updateTime", "tenantId"}; /** * 文本框 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 index dec9c8bde..ed1ea1a8f 100644 --- 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 @@ -1,14 +1,16 @@ package com.ruoyi.generator.domain; -import com.baomidou.mybatisplus.annotation.*; -import com.ruoyi.generator.constant.GenConstants; +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 org.apache.commons.lang3.ArrayUtils; import java.util.List; @@ -183,10 +185,6 @@ public class GenTable extends BaseEntity { } public static boolean isSuperColumn(String tplCategory, String javaField) { - if (isTree(tplCategory)) { - return StringUtils.equalsAnyIgnoreCase(javaField, - ArrayUtils.addAll(GenConstants.TREE_ENTITY, GenConstants.BASE_ENTITY)); - } 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 index 5a4c3cf18..f374bf9f8 100644 --- 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 @@ -212,7 +212,7 @@ public class GenTableColumn extends BaseEntity { if (StringUtils.isNotEmpty(value)) { Object startStr = value.subSequence(0, 1); String endStr = value.substring(1); - sb.append("").append(startStr).append("=").append(endStr).append(","); + sb.append(StringUtils.EMPTY).append(startStr).append("=").append(endStr).append(StringUtils.SEPARATOR); } } return sb.deleteCharAt(sb.length() - 1).toString(); 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 index 77275ef69..5a9286f3b 100644 --- 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 @@ -59,7 +59,7 @@ public class GenUtils { column.setHtmlType(GenConstants.HTML_INPUT); // 如果是浮点型 统一用BigDecimal - String[] str = StringUtils.split(StringUtils.substringBetween(column.getColumnType(), "(", ")"), ","); + 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); } @@ -168,7 +168,7 @@ public class GenUtils { boolean autoRemovePre = GenConfig.getAutoRemovePre(); String tablePrefix = GenConfig.getTablePrefix(); if (autoRemovePre && StringUtils.isNotEmpty(tablePrefix)) { - String[] searchList = StringUtils.split(tablePrefix, ","); + String[] searchList = StringUtils.split(tablePrefix, StringUtils.SEPARATOR); tableName = replaceFirst(tableName, searchList); } return StringUtils.convertToCamelCase(tableName); 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 index 7b3cd018b..b1557fca2 100644 --- 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 @@ -225,7 +225,7 @@ public class VelocityUtils { */ public static String getDicts(GenTable genTable) { List columns = genTable.getColumns(); - Set dicts = new HashSet(); + Set dicts = new HashSet<>(); addDicts(dicts, columns); return StringUtils.join(dicts, ", "); } 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 1989e06d0..e23520297 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,21 +1,16 @@ package ${packageName}.domain.bo; +import com.ruoyi.common.mybatis.core.domain.BaseEntity; import com.ruoyi.common.core.validate.AddGroup; import com.ruoyi.common.core.validate.EditGroup; import lombok.Data; import lombok.EqualsAndHashCode; import jakarta.validation.constraints.*; - -import java.util.Date; - #foreach ($import in $importList) import ${import}; #end -#if($table.crud || $table.sub) -import com.ruoyi.common.mybatis.core.domain.BaseEntity; -#elseif($table.tree) -import com.ruoyi.common.mybatis.core.domain.TreeEntity; -#end + +import java.util.Date; /** * ${functionName}业务对象 ${tableName} @@ -23,15 +18,9 @@ import com.ruoyi.common.mybatis.core.domain.TreeEntity; * @author ${author} * @date ${datetime} */ -#if($table.crud || $table.sub) -#set($Entity="BaseEntity") -#elseif($table.tree) -#set($Entity="TreeEntity<${ClassName}Bo>") -#end - @Data @EqualsAndHashCode(callSuper = true) -public class ${ClassName}Bo extends ${Entity} { +public class ${ClassName}Bo extends BaseEntity { #foreach ($column in $columns) #if(!$table.isSuperColumn($column.javaField) && ($column.query || $column.isInsert || $column.isEdit)) 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 ee6fdd2e4..761284fb9 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 @@ -39,7 +39,7 @@ import com.ruoyi.common.mybatis.core.page.TableDataInfo; @RequestMapping("/${moduleName}/${businessName}") public class ${ClassName}Controller extends BaseController { - private final I${ClassName}Service i${ClassName}Service; + private final I${ClassName}Service ${className}Service; /** * 查询${functionName}列表 @@ -52,7 +52,7 @@ public class ${ClassName}Controller extends BaseController { } #elseif($table.tree) public R> list(${ClassName}Bo bo) { - List<${ClassName}Vo> list = i${ClassName}Service.queryList(bo); + List<${ClassName}Vo> list = ${className}Service.queryList(bo); return R.ok(list); } #end @@ -64,7 +64,7 @@ public class ${ClassName}Controller extends BaseController { @Log(title = "${functionName}", businessType = BusinessType.EXPORT) @PostMapping("/export") public void export(${ClassName}Bo bo, HttpServletResponse response) { - List<${ClassName}Vo> list = i${ClassName}Service.queryList(bo); + List<${ClassName}Vo> list = ${className}Service.queryList(bo); ExcelUtil.exportExcel(list, "${functionName}", ${ClassName}Vo.class, response); } @@ -77,7 +77,7 @@ public class ${ClassName}Controller extends BaseController { @GetMapping("/{${pkColumn.javaField}}") public R<${ClassName}Vo> getInfo(@NotNull(message = "主键不能为空") @PathVariable ${pkColumn.javaType} ${pkColumn.javaField}) { - return R.ok(i${ClassName}Service.queryById(${pkColumn.javaField})); + return R.ok(${className}Service.queryById(${pkColumn.javaField})); } /** @@ -88,7 +88,7 @@ public class ${ClassName}Controller extends BaseController { @RepeatSubmit() @PostMapping() public R add(@Validated(AddGroup.class) @RequestBody ${ClassName}Bo bo) { - return toAjax(i${ClassName}Service.insertByBo(bo)); + return toAjax(${className}Service.insertByBo(bo)); } /** @@ -99,7 +99,7 @@ public class ${ClassName}Controller extends BaseController { @RepeatSubmit() @PutMapping() public R edit(@Validated(EditGroup.class) @RequestBody ${ClassName}Bo bo) { - return toAjax(i${ClassName}Service.updateByBo(bo)); + return toAjax(${className}Service.updateByBo(bo)); } /** @@ -112,6 +112,6 @@ public class ${ClassName}Controller extends BaseController { @DeleteMapping("/{${pkColumn.javaField}s}") public R remove(@NotEmpty(message = "主键不能为空") @PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s) { - return toAjax(i${ClassName}Service.deleteWithValidByIds(List.of(${pkColumn.javaField}s), true)); + return toAjax(${className}Service.deleteWithValidByIds(List.of(${pkColumn.javaField}s), true)); } } 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 6e0f6a23e..f176ecd5a 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 @@ -1,21 +1,25 @@ package ${packageName}.domain; +#foreach ($column in $columns) +#if($column.javaField=='tenantId') +#set($IsTenant=1) +#end +#end +#if($IsTenant==1) +import com.ruoyi.common.tenant.core.TenantEntity; +#else +import com.ruoyi.common.mybatis.core.domain.BaseEntity; +#end import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import lombok.EqualsAndHashCode; -import java.io.Serial; -import java.io.Serializable; -import java.util.Date; -import java.math.BigDecimal; - #foreach ($import in $importList) import ${import}; #end -#if($table.crud || $table.sub) -import com.ruoyi.common.mybatis.core.domain.BaseEntity; -#elseif($table.tree) -import com.ruoyi.common.mybatis.core.domain.TreeEntity; -#end + +import java.io.Serial; +import java.util.Date; +import java.math.BigDecimal; /** * ${functionName}对象 ${tableName} @@ -23,10 +27,10 @@ import com.ruoyi.common.mybatis.core.domain.TreeEntity; * @author ${author} * @date ${datetime} */ -#if($table.crud || $table.sub) - #set($Entity="BaseEntity") -#elseif($table.tree) - #set($Entity="TreeEntity<${ClassName}>") +#if($IsTenant==1) +#set($Entity="TenantEntity") +#else +#set($Entity="BaseEntity") #end @Data @EqualsAndHashCode(callSuper = true) @@ -51,6 +55,7 @@ public class ${ClassName} extends ${Entity} { @TableId(value = "$column.columnName") #end private $column.javaType $column.javaField; + #end #end diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm index 2bc699a20..1dcf0b915 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm +++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm @@ -333,6 +333,7 @@ export default { // 表单校验 rules: { #foreach ($column in $columns) +#if($column.isInsert || $column.isEdit) #if($column.required) #set($parentheseIndex=$column.columnComment.indexOf("(")) #if($parentheseIndex != -1) @@ -344,6 +345,7 @@ export default { { required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end } ]#if($foreach.count != $columns.size()),#end #end +#end #end } }; @@ -404,11 +406,13 @@ export default { reset() { this.form = { #foreach ($column in $columns) +#if($column.isInsert || $column.isEdit) #if($column.htmlType == "checkbox") $column.javaField: []#if($foreach.count != $columns.size()),#end #else $column.javaField: null#if($foreach.count != $columns.size()),#end #end +#end #end }; this.resetForm("form"); diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm index 9f0131b71..3e7628e29 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm +++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm @@ -343,6 +343,7 @@ export default { // 表单校验 rules: { #foreach ($column in $columns) +#if($column.isInsert || $column.isEdit) #if($column.required) #set($parentheseIndex=$column.columnComment.indexOf("(")) #if($parentheseIndex != -1) @@ -354,6 +355,7 @@ export default { { required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end } ]#if($foreach.count != $columns.size()),#end #end +#end #end } }; @@ -395,11 +397,13 @@ export default { reset() { this.form = { #foreach ($column in $columns) +#if($column.isInsert || $column.isEdit) #if($column.htmlType == "checkbox") $column.javaField: []#if($foreach.count != $columns.size()),#end #else $column.javaField: undefined#if($foreach.count != $columns.size()),#end #end +#end #end }; this.resetForm("form"); diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm index 663893a2c..31091a3b1 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm +++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm @@ -304,6 +304,7 @@ const data = reactive({ }, rules: { #foreach ($column in $columns) +#if($column.isInsert || $column.isEdit) #if($column.required) #set($parentheseIndex=$column.columnComment.indexOf("(")) #if($parentheseIndex != -1) @@ -315,6 +316,7 @@ const data = reactive({ { required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end } ]#if($foreach.count != $columns.size()),#end #end +#end #end } }); @@ -365,11 +367,13 @@ function cancel() { function reset() { form.value = { #foreach ($column in $columns) +#if($column.isInsert || $column.isEdit) #if($column.htmlType == "checkbox") $column.javaField: []#if($foreach.count != $columns.size()),#end #else $column.javaField: null#if($foreach.count != $columns.size()),#end #end +#end #end }; proxy.resetForm("${businessName}Ref"); diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/v3/index.vue.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/v3/index.vue.vm index e623295c1..2a2deb49b 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/v3/index.vue.vm +++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/v3/index.vue.vm @@ -315,6 +315,7 @@ const data = reactive({ }, rules: { #foreach ($column in $columns) +#if($column.isInsert || $column.isEdit) #if($column.required) #set($parentheseIndex=$column.columnComment.indexOf("(")) #if($parentheseIndex != -1) @@ -326,6 +327,7 @@ const data = reactive({ { required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end } ]#if($foreach.count != $columns.size()),#end #end +#end #end } }); @@ -367,11 +369,13 @@ function cancel() { function reset() { form.value = { #foreach ($column in $columns) +#if($column.isInsert || $column.isEdit) #if($column.htmlType == "checkbox") $column.javaField: []#if($foreach.count != $columns.size()),#end #else $column.javaField: null#if($foreach.count != $columns.size()),#end #end +#end #end }; proxy.resetForm("${businessName}Ref"); diff --git a/ruoyi-modules/ruoyi-system/pom.xml b/ruoyi-modules/ruoyi-system/pom.xml index 7f3572b61..be1c3ceee 100644 --- a/ruoyi-modules/ruoyi-system/pom.xml +++ b/ruoyi-modules/ruoyi-system/pom.xml @@ -63,7 +63,7 @@ com.ruoyi - ruoyi-common-satoken + ruoyi-common-tenant 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 03fc761ad..000000000 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/monitor/CacheController.java +++ /dev/null @@ -1,168 +0,0 @@ -package com.ruoyi.system.controller.monitor; - -import cn.dev33.satoken.annotation.SaCheckPermission; -import cn.hutool.core.collection.CollUtil; -import com.ruoyi.common.core.constant.CacheConstants; -import com.ruoyi.common.core.constant.CacheNames; -import com.ruoyi.common.core.domain.R; -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.redis.utils.CacheUtils; -import com.ruoyi.common.redis.utils.RedisUtils; -import com.ruoyi.system.domain.SysCache; -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.*; - -import java.util.*; - -/** - * 缓存监控 - * - * @author Lion Li - */ -@RequiredArgsConstructor -@RestController -@RequestMapping("/monitor/cache") -public class CacheController { - - private final RedissonConnectionFactory connectionFactory; - - private final static List CACHES = new ArrayList<>(); - - static { - CACHES.add(new SysCache(CacheConstants.LOGIN_TOKEN_KEY, "用户信息")); - CACHES.add(new SysCache(CacheConstants.ONLINE_TOKEN_KEY, "在线用户")); - CACHES.add(new SysCache(CacheNames.SYS_CONFIG, "配置信息")); - CACHES.add(new SysCache(CacheNames.SYS_DICT, "数据字典")); - CACHES.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码")); - CACHES.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "防重提交")); - CACHES.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "限流处理")); - CACHES.add(new SysCache(CacheNames.SYS_OSS_CONFIG, "OSS配置")); - CACHES.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "密码错误次数")); - } - - /** - * 获取缓存监控列表 - */ - @SaCheckPermission("monitor:cache:list") - @GetMapping() - public R getInfo() throws Exception { - RedisConnection connection = connectionFactory.getConnection(); - Properties commandStats = connection.commands().info("commandstats"); - - List> pieList = new ArrayList<>(); - if (commandStats != null) { - commandStats.stringPropertyNames().forEach(key -> { - Map 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); - } - - /** - * 获取缓存监控缓存名列表 - */ - @SaCheckPermission("monitor:cache:list") - @GetMapping("/getNames") - public R> cache() { - return R.ok(CACHES); - } - - /** - * 获取缓存监控Key列表 - * - * @param cacheName 缓存名 - */ - @SaCheckPermission("monitor:cache:list") - @GetMapping("/getKeys/{cacheName}") - public R> getCacheKeys(@PathVariable String cacheName) { - Collection cacheKeys = new HashSet<>(0); - if (isCacheNames(cacheName)) { - Set keys = CacheUtils.keys(cacheName); - if (CollUtil.isNotEmpty(keys)) { - cacheKeys = StreamUtils.toList(keys, Object::toString); - } - } else { - cacheKeys = RedisUtils.keys(cacheName + "*"); - } - return R.ok(cacheKeys); - } - - /** - * 获取缓存监控缓存值详情 - * - * @param cacheName 缓存名 - * @param cacheKey 缓存key - */ - @SaCheckPermission("monitor:cache:list") - @GetMapping("/getValue/{cacheName}/{cacheKey}") - public R getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey) { - Object cacheValue; - if (isCacheNames(cacheName)) { - cacheValue = CacheUtils.get(cacheName, cacheKey); - } else { - cacheValue = RedisUtils.getCacheObject(cacheKey); - } - SysCache sysCache = new SysCache(cacheName, cacheKey, JsonUtils.toJsonString(cacheValue)); - return R.ok(sysCache); - } - - /** - * 清理缓存监控缓存名 - * - * @param cacheName 缓存名 - */ - @SaCheckPermission("monitor:cache:list") - @DeleteMapping("/clearCacheName/{cacheName}") - public R clearCacheName(@PathVariable String cacheName) { - if (isCacheNames(cacheName)) { - CacheUtils.clear(cacheName); - } else { - RedisUtils.deleteKeys(cacheName + "*"); - } - return R.ok(); - } - - /** - * 清理缓存监控Key - * - * @param cacheKey key名 - */ - @SaCheckPermission("monitor:cache:list") - @DeleteMapping("/clearCacheKey/{cacheName}/{cacheKey}") - public R clearCacheKey(@PathVariable String cacheName, @PathVariable String cacheKey) { - if (isCacheNames(cacheName)) { - CacheUtils.evict(cacheName, cacheKey); - } else { - RedisUtils.deleteObject(cacheKey); - } - return R.ok(); - } - - /** - * 清理全部缓存监控 - */ - @SaCheckPermission("monitor:cache:list") - @DeleteMapping("/clearCacheAll") - public R clearCacheAll() { - RedisUtils.deleteKeys("*"); - return R.ok(); - } - - private boolean isCacheNames(String cacheName) { - return !StringUtils.contains(cacheName, ":"); - } -} 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 index c937e609d..1ef7f7fbe 100644 --- 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 @@ -1,22 +1,23 @@ package com.ruoyi.system.controller.monitor; import cn.dev33.satoken.annotation.SaCheckPermission; -import com.ruoyi.common.core.constant.CacheConstants; -import com.ruoyi.common.mybatis.core.page.PageQuery; +import com.ruoyi.common.core.constant.GlobalConstants; import com.ruoyi.common.core.domain.R; -import com.ruoyi.common.mybatis.core.page.TableDataInfo; -import com.ruoyi.common.web.core.BaseController; 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.system.domain.SysLogininfor; +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 jakarta.servlet.http.HttpServletResponse; import java.util.List; /** @@ -37,7 +38,7 @@ public class SysLogininforController extends BaseController { */ @SaCheckPermission("monitor:logininfor:list") @GetMapping("/list") - public TableDataInfo list(SysLogininfor logininfor, PageQuery pageQuery) { + public TableDataInfo list(SysLogininforBo logininfor, PageQuery pageQuery) { return logininforService.selectPageLogininforList(logininfor, pageQuery); } @@ -47,9 +48,9 @@ public class SysLogininforController extends BaseController { @Log(title = "登录日志", businessType = BusinessType.EXPORT) @SaCheckPermission("monitor:logininfor:export") @PostMapping("/export") - public void export(SysLogininfor logininfor, HttpServletResponse response) { - List list = logininforService.selectLogininforList(logininfor); - ExcelUtil.exportExcel(list, "登录日志", SysLogininfor.class, response); + public void export(SysLogininforBo logininfor, HttpServletResponse response) { + List list = logininforService.selectLogininforList(logininfor); + ExcelUtil.exportExcel(list, "登录日志", SysLogininforVo.class, response); } /** @@ -78,7 +79,7 @@ public class SysLogininforController extends BaseController { @Log(title = "账户解锁", businessType = BusinessType.OTHER) @GetMapping("/unlock/{userName}") public R unlock(@PathVariable("userName") String userName) { - String loginName = CacheConstants.PWD_ERR_CNT_KEY + userName; + String loginName = GlobalConstants.PWD_ERR_CNT_KEY + userName; if (RedisUtils.hasKey(loginName)) { RedisUtils.deleteObject(loginName); } 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 index a985497fc..279389095 100644 --- 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 @@ -8,7 +8,8 @@ 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.SysOperLog; +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; @@ -35,7 +36,7 @@ public class SysOperlogController extends BaseController { */ @SaCheckPermission("monitor:operlog:list") @GetMapping("/list") - public TableDataInfo list(SysOperLog operLog, PageQuery pageQuery) { + public TableDataInfo list(SysOperLogBo operLog, PageQuery pageQuery) { return operLogService.selectPageOperLogList(operLog, pageQuery); } @@ -45,9 +46,9 @@ public class SysOperlogController extends BaseController { @Log(title = "操作日志", businessType = BusinessType.EXPORT) @SaCheckPermission("monitor:operlog:export") @PostMapping("/export") - public void export(SysOperLog operLog, HttpServletResponse response) { - List list = operLogService.selectOperLogList(operLog); - ExcelUtil.exportExcel(list, "操作日志", SysOperLog.class, response); + public void export(SysOperLogBo operLog, HttpServletResponse response) { + List list = operLogService.selectOperLogList(operLog); + ExcelUtil.exportExcel(list, "操作日志", SysOperLogVo.class, response); } /** 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 index bebfad251..9daa394d7 100644 --- 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 @@ -4,16 +4,17 @@ 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.log.annotation.Log; import com.ruoyi.common.core.constant.CacheConstants; -import com.ruoyi.common.web.core.BaseController; +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.mybatis.core.page.TableDataInfo; -import com.ruoyi.common.log.enums.BusinessType; 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.*; @@ -45,7 +46,7 @@ public class SysUserOnlineController extends BaseController { List keys = StpUtil.searchTokenValue("", 0, -1, false); List userOnlineDTOList = new ArrayList<>(); for (String key : keys) { - String token = key.replace(CacheConstants.LOGIN_TOKEN_KEY, ""); + String token = key.replace(GlobalConstants.LOGIN_TOKEN_KEY, ""); // 如果已经过期则跳过 if (StpUtil.stpLogic.getTokenActivityTimeoutByToken(token) < -1) { continue; 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 index 316497c81..90e134cd9 100644 --- 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 @@ -1,13 +1,13 @@ package com.ruoyi.system.controller.system; import cn.dev33.satoken.annotation.SaCheckPermission; -import cn.hutool.core.util.ArrayUtil; -import com.ruoyi.common.log.annotation.Log; +import cn.hutool.core.convert.Convert; import com.ruoyi.common.core.constant.UserConstants; -import com.ruoyi.common.web.core.BaseController; import com.ruoyi.common.core.domain.R; -import com.ruoyi.common.log.enums.BusinessType; 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; @@ -50,7 +50,7 @@ public class SysDeptController extends BaseController { public R> excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) { List depts = deptService.selectDeptList(new SysDeptBo()); depts.removeIf(d -> d.getDeptId().equals(deptId) - || ArrayUtil.contains(StringUtils.split(d.getAncestors(), ","), deptId + "")); + || StringUtils.splitList(d.getAncestors()).contains(Convert.toStr(deptId))); return R.ok(depts); } 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 index b40acbbae..6914d4ec5 100644 --- 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 @@ -1,7 +1,10 @@ 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; @@ -35,6 +38,10 @@ public class SysMenuController extends BaseController { /** * 获取菜单列表 */ + @SaCheckRole(value = { + TenantConstants.SUPER_ADMIN_ROLE_KEY, + TenantConstants.TENANT_ADMIN_ROLE_KEY + }, mode = SaMode.OR) @SaCheckPermission("system:menu:list") @GetMapping("/list") public R> list(SysMenuBo menu) { @@ -47,6 +54,10 @@ public class SysMenuController extends BaseController { * * @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 getInfo(@PathVariable Long menuId) { @@ -56,6 +67,11 @@ public class SysMenuController extends BaseController { /** * 获取菜单下拉树列表 */ + @SaCheckRole(value = { + TenantConstants.SUPER_ADMIN_ROLE_KEY, + TenantConstants.TENANT_ADMIN_ROLE_KEY + }, mode = SaMode.OR) + @SaCheckPermission("system:menu:query") @GetMapping("/treeselect") public R>> treeselect(SysMenuBo menu) { List menus = menuService.selectMenuList(menu, LoginHelper.getUserId()); @@ -67,6 +83,11 @@ public class SysMenuController extends BaseController { * * @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 roleMenuTreeselect(@PathVariable("roleId") Long roleId) { List menus = menuService.selectMenuList(LoginHelper.getUserId()); @@ -76,9 +97,26 @@ public class SysMenuController extends BaseController { return R.ok(selectVo); } + /** + * 加载对应租户套餐菜单列表树 + * + * @param packageId 租户套餐ID + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @SaCheckPermission("system:menu:query") + @GetMapping(value = "/tenantPackageMenuTreeselect/{packageId}") + public R tenantPackageMenuTreeselect(@PathVariable("packageId") Long packageId) { + List 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 @@ -94,6 +132,7 @@ public class SysMenuController extends BaseController { /** * 修改菜单 */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) @SaCheckPermission("system:menu:edit") @Log(title = "菜单管理", businessType = BusinessType.UPDATE) @PutMapping @@ -113,6 +152,7 @@ public class SysMenuController extends BaseController { * * @param menuId 菜单ID */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) @SaCheckPermission("system:menu:remove") @Log(title = "菜单管理", businessType = BusinessType.DELETE) @DeleteMapping("/{menuId}") @@ -125,4 +165,5 @@ public class SysMenuController extends BaseController { } return toAjax(menuService.deleteMenuById(menuId)); } + } 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 index b899559e4..7c27230f3 100644 --- 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 @@ -35,7 +35,7 @@ import java.util.List; @RequestMapping("/system/oss/config") public class SysOssConfigController extends BaseController { - private final ISysOssConfigService iSysOssConfigService; + private final ISysOssConfigService sysOssConfigService; /** * 查询对象存储配置列表 @@ -43,7 +43,7 @@ public class SysOssConfigController extends BaseController { @SaCheckPermission("system:oss:list") @GetMapping("/list") public TableDataInfo list(@Validated(QueryGroup.class) SysOssConfigBo bo, PageQuery pageQuery) { - return iSysOssConfigService.queryPageList(bo, pageQuery); + return sysOssConfigService.queryPageList(bo, pageQuery); } /** @@ -55,7 +55,7 @@ public class SysOssConfigController extends BaseController { @GetMapping("/{ossConfigId}") public R getInfo(@NotNull(message = "主键不能为空") @PathVariable Long ossConfigId) { - return R.ok(iSysOssConfigService.queryById(ossConfigId)); + return R.ok(sysOssConfigService.queryById(ossConfigId)); } /** @@ -66,7 +66,7 @@ public class SysOssConfigController extends BaseController { @RepeatSubmit() @PostMapping() public R add(@Validated(AddGroup.class) @RequestBody SysOssConfigBo bo) { - return toAjax(iSysOssConfigService.insertByBo(bo)); + return toAjax(sysOssConfigService.insertByBo(bo)); } /** @@ -77,7 +77,7 @@ public class SysOssConfigController extends BaseController { @RepeatSubmit() @PutMapping() public R edit(@Validated(EditGroup.class) @RequestBody SysOssConfigBo bo) { - return toAjax(iSysOssConfigService.updateByBo(bo)); + return toAjax(sysOssConfigService.updateByBo(bo)); } /** @@ -90,7 +90,7 @@ public class SysOssConfigController extends BaseController { @DeleteMapping("/{ossConfigIds}") public R remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ossConfigIds) { - return toAjax(iSysOssConfigService.deleteWithValidByIds(List.of(ossConfigIds), true)); + return toAjax(sysOssConfigService.deleteWithValidByIds(List.of(ossConfigIds), true)); } /** @@ -100,6 +100,6 @@ public class SysOssConfigController extends BaseController { @Log(title = "对象存储状态修改", businessType = BusinessType.UPDATE) @PutMapping("/changeStatus") public R changeStatus(@RequestBody SysOssConfigBo bo) { - return toAjax(iSysOssConfigService.updateOssConfigStatus(bo)); + return toAjax(sysOssConfigService.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 index 993de54a9..d03bfcddb 100644 --- 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 @@ -38,7 +38,7 @@ import java.util.List; @RequestMapping("/system/oss") public class SysOssController extends BaseController { - private final ISysOssService iSysOssService; + private final ISysOssService sysOssService; /** * 查询OSS对象存储列表 @@ -46,7 +46,7 @@ public class SysOssController extends BaseController { @SaCheckPermission("system:oss:list") @GetMapping("/list") public TableDataInfo list(@Validated(QueryGroup.class) SysOssBo bo, PageQuery pageQuery) { - return iSysOssService.queryPageList(bo, pageQuery); + return sysOssService.queryPageList(bo, pageQuery); } /** @@ -58,7 +58,7 @@ public class SysOssController extends BaseController { @GetMapping("/listByIds/{ossIds}") public R> listByIds(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ossIds) { - List list = iSysOssService.listByIds(Arrays.asList(ossIds)); + List list = sysOssService.listByIds(Arrays.asList(ossIds)); return R.ok(list); } @@ -74,7 +74,7 @@ public class SysOssController extends BaseController { if (ObjectUtil.isNull(file)) { throw new ServiceException("上传文件不能为空"); } - SysOssVo oss = iSysOssService.upload(file); + SysOssVo oss = sysOssService.upload(file); SysOssUploadVo uploadVo = new SysOssUploadVo(); uploadVo.setUrl(oss.getUrl()); uploadVo.setFileName(oss.getOriginalName()); @@ -90,7 +90,7 @@ public class SysOssController extends BaseController { @SaCheckPermission("system:oss:download") @GetMapping("/download/{ossId}") public void download(@PathVariable Long ossId, HttpServletResponse response) throws IOException { - iSysOssService.download(ossId, response); + sysOssService.download(ossId, response); } /** @@ -103,7 +103,7 @@ public class SysOssController extends BaseController { @DeleteMapping("/{ossIds}") public R remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ossIds) { - return toAjax(iSysOssService.deleteWithValidByIds(List.of(ossIds), true)); + return toAjax(sysOssService.deleteWithValidByIds(List.of(ossIds), true)); } } 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 index 5e84c07d2..7a2d5bb69 100644 --- 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 @@ -39,7 +39,7 @@ import java.util.Arrays; public class SysProfileController extends BaseController { private final ISysUserService userService; - private final ISysOssService iSysOssService; + private final ISysOssService sysOssService; /** * 个人信息 @@ -114,7 +114,7 @@ public class SysProfileController extends BaseController { if (!StringUtils.equalsAnyIgnoreCase(extension, MimeTypeUtils.IMAGE_EXTENSION)) { return R.fail("文件格式不正确,请上传" + Arrays.toString(MimeTypeUtils.IMAGE_EXTENSION) + "格式"); } - SysOssVo oss = iSysOssService.upload(avatarfile); + SysOssVo oss = sysOssService.upload(avatarfile); String avatar = oss.getUrl(); if (userService.updateUserAvatar(LoginHelper.getUsername(), oss.getOssId())) { AvatarVo avatarVo = new AvatarVo(); 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 index 02dc7ab21..a3cf5a0b8 100644 --- 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 @@ -1,16 +1,13 @@ package com.ruoyi.system.controller.system; import cn.dev33.satoken.annotation.SaCheckPermission; -import cn.hutool.core.util.ObjectUtil; import com.ruoyi.common.core.constant.UserConstants; 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.SysDept; import com.ruoyi.system.domain.SysUserRole; @@ -20,9 +17,9 @@ 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.ISysPermissionService; import com.ruoyi.system.service.ISysRoleService; import com.ruoyi.system.service.ISysUserService; -import com.ruoyi.system.service.SysPermissionService; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; @@ -44,7 +41,7 @@ public class SysRoleController extends BaseController { private final ISysRoleService roleService; private final ISysUserService userService; private final ISysDeptService deptService; - private final SysPermissionService permissionService; + private final ISysPermissionService permissionService; /** * 获取角色信息列表 @@ -110,13 +107,14 @@ public class SysRoleController extends BaseController { } if (roleService.updateRole(role) > 0) { - // 更新缓存用户权限 - LoginUser loginUser = LoginHelper.getLoginUser(); - SysUserVo sysUser = userService.selectUserById(loginUser.getUserId()); - if (ObjectUtil.isNotNull(sysUser) && !LoginHelper.isAdmin()) { - loginUser.setMenuPermission(permissionService.getMenuPermission(sysUser.getUserId(), sysUser.isAdmin())); - LoginHelper.setLoginUser(loginUser); - } +// // 更新缓存用户权限 +// LoginUser loginUser = LoginHelper.getLoginUser(); +// SysUserVo sysUser = userService.selectUserById(loginUser.getUserId()); +// if (ObjectUtil.isNotNull(sysUser)) { +// loginUser.setMenuPermission(permissionService.getMenuPermission(sysUser.getUserId())); +// LoginHelper.setLoginUser(loginUser); +// } + // todo LoginUser 改为存储到token内部 无法热更新 等待后续想办法 return R.ok(); } return R.fail("修改角色'" + role.getRoleName() + "'失败,请联系管理员"); 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 new file mode 100644 index 000000000..5a582caf7 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysTenantController.java @@ -0,0 +1,168 @@ +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.constant.UserConstants; +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.bo.SysUserBo; +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 sysTenantService; + private final ISysUserService sysUserService; + + /** + * 查询租户列表 + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @SaCheckPermission("system:tenant:list") + @GetMapping("/list") + public TableDataInfo list(SysTenantBo bo, PageQuery pageQuery) { + return sysTenantService.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 list = sysTenantService.queryList(bo); + ExcelUtil.exportExcel(list, "租户", SysTenantVo.class, response); + } + + /** + * 获取租户详细信息 + * + * @param id 主键 + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @SaCheckPermission("system:tenant:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(sysTenantService.queryById(id)); + } + + /** + * 新增租户 + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @SaCheckPermission("system:tenant:add") + @Log(title = "租户", businessType = BusinessType.INSERT) + @Lock4j + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody SysTenantBo bo) { + if (TenantConstants.NOT_PASS.equals(sysTenantService.checkCompanyNameUnique(bo))) { + throw new ServiceException("新增租户'" + bo.getCompanyName() + "'失败,企业名称已存在"); + } + SysUserBo userBo = new SysUserBo(); + userBo.setUserName(bo.getUsername()); + // 判断用户名是否重复 + if (UserConstants.NOT_UNIQUE.equals(sysUserService.checkUserNameUnique(userBo))) { + throw new ServiceException("新增用户'" + bo.getUsername() + "'失败,登录账号已存在"); + } + return toAjax(sysTenantService.insertByBo(bo)); + } + + /** + * 修改租户 + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @SaCheckPermission("system:tenant:edit") + @Log(title = "租户", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody SysTenantBo bo) { + if (UserConstants.NOT_UNIQUE.equals(sysTenantService.checkCompanyNameUnique(bo))) { + throw new ServiceException("修改租户'" + bo.getCompanyName() + "'失败,公司名称已存在"); + } + return toAjax(sysTenantService.updateByBo(bo)); + } + + /** + * 状态修改 + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @SaCheckPermission("system:tenantPackage:edit") + @Log(title = "租户套餐", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public R changeStatus(@RequestBody SysTenantBo bo) { + return toAjax(sysTenantService.updateTenantStatus(bo)); + } + + /** + * 删除租户 + * + * @param ids 主键串 + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @SaCheckPermission("system:tenant:remove") + @Log(title = "租户", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(sysTenantService.deleteWithValidByIds(List.of(ids), true)); + } + + /** + * 动态切换租户 + * + * @param tenantId 租户ID + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @GetMapping("/dynamic/{tenantId}") + public R dynamicTenant(@NotBlank(message = "租户ID不能为空") @PathVariable String tenantId) { + TenantHelper.setDynamic(tenantId); + return R.ok(); + } + + /** + * 清除动态租户 + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @GetMapping("/dynamic/clear") + public R dynamicClear() { + TenantHelper.clearDynamic(); + return R.ok(); + } + +} 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 new file mode 100644 index 000000000..a0626c37a --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysTenantPackageController.java @@ -0,0 +1,124 @@ +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 sysTenantPackageService; + + /** + * 查询租户套餐列表 + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @SaCheckPermission("system:tenantPackage:list") + @GetMapping("/list") + public TableDataInfo list(SysTenantPackageBo bo, PageQuery pageQuery) { + return sysTenantPackageService.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 list = sysTenantPackageService.queryList(bo); + ExcelUtil.exportExcel(list, "租户套餐", SysTenantPackageVo.class, response); + } + + /** + * 获取租户套餐详细信息 + * + * @param packageId 主键 + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @SaCheckPermission("system:tenantPackage:query") + @GetMapping("/{packageId}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long packageId) { + return R.ok(sysTenantPackageService.queryById(packageId)); + } + + /** + * 新增租户套餐 + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @SaCheckPermission("system:tenantPackage:add") + @Log(title = "租户套餐", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody SysTenantPackageBo bo) { + return toAjax(sysTenantPackageService.insertByBo(bo)); + } + + /** + * 修改租户套餐 + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @SaCheckPermission("system:tenantPackage:edit") + @Log(title = "租户套餐", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody SysTenantPackageBo bo) { + return toAjax(sysTenantPackageService.updateByBo(bo)); + } + + /** + * 状态修改 + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @SaCheckPermission("system:tenantPackage:edit") + @Log(title = "租户套餐", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public R changeStatus(@RequestBody SysTenantPackageBo bo) { + return toAjax(sysTenantPackageService.updatePackageStatus(bo)); + } + + /** + * 删除租户套餐 + * + * @param packageIds 主键串 + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @SaCheckPermission("system:tenantPackage:remove") + @Log(title = "租户套餐", businessType = BusinessType.DELETE) + @DeleteMapping("/{packageIds}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] packageIds) { + return toAjax(sysTenantPackageService.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 index 0efea3de0..1bec7a568 100644 --- 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 @@ -6,6 +6,7 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.util.ArrayUtil; 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.R; import com.ruoyi.common.core.utils.StreamUtils; @@ -16,16 +17,14 @@ 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.satoken.utils.LoginHelper; import com.ruoyi.common.web.core.BaseController; import com.ruoyi.system.domain.SysDept; import com.ruoyi.system.domain.bo.SysUserBo; import com.ruoyi.system.domain.vo.*; import com.ruoyi.system.listener.SysUserImportListener; -import com.ruoyi.system.service.ISysDeptService; -import com.ruoyi.system.service.ISysPostService; -import com.ruoyi.system.service.ISysRoleService; -import com.ruoyi.system.service.ISysUserService; +import com.ruoyi.system.service.*; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.springframework.http.MediaType; @@ -51,6 +50,7 @@ public class SysUserController extends BaseController { private final ISysRoleService roleService; private final ISysPostService postService; private final ISysDeptService deptService; + private final ISysTenantService tenantService; /** * 获取用户列表 @@ -114,7 +114,7 @@ public class SysUserController extends BaseController { userService.checkUserDataScope(userId); SysUserInfoVo userInfoVo = new SysUserInfoVo(); List roles = roleService.selectRoleAll(); - userInfoVo.setRoles(LoginHelper.isAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isAdmin())); + 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); @@ -141,6 +141,12 @@ public class SysUserController extends BaseController { && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) { return R.fail("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在"); } + if (TenantHelper.isEnable()) { + String status = tenantService.checkAccountBalance(LoginHelper.getTenantId()); + if (TenantConstants.NOT_PASS.equals(status)) { + return R.fail("当前租户下用户名额不足,请联系管理员"); + } + } user.setPassword(BCrypt.hashpw(user.getPassword())); return toAjax(userService.insertUser(user)); } @@ -218,7 +224,7 @@ public class SysUserController extends BaseController { List roles = roleService.selectRolesByUserId(userId); SysUserInfoVo userInfoVo = new SysUserInfoVo(); userInfoVo.setUser(user); - userInfoVo.setRoles(LoginHelper.isAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isAdmin())); + userInfoVo.setRoles(LoginHelper.isSuperAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isSuperAdmin())); return R.ok(userInfoVo); } 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 index 20b902de6..3e6217107 100644 --- 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 @@ -2,7 +2,7 @@ package com.ruoyi.system.domain; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import com.ruoyi.common.mybatis.core.domain.BaseEntity; +import com.ruoyi.common.tenant.core.TenantEntity; import lombok.Data; import lombok.EqualsAndHashCode; @@ -15,7 +15,7 @@ import lombok.EqualsAndHashCode; @Data @EqualsAndHashCode(callSuper = true) @TableName("sys_config") -public class SysConfig extends BaseEntity { +public class SysConfig extends TenantEntity { /** * 参数主键 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 index eb3b1dc93..efa67ffbf 100644 --- 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 @@ -3,11 +3,7 @@ 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.TreeEntity; -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; +import com.ruoyi.common.tenant.core.TenantEntity; import lombok.Data; import lombok.EqualsAndHashCode; @@ -22,7 +18,7 @@ import java.io.Serial; @Data @EqualsAndHashCode(callSuper = true) @TableName("sys_dept") -public class SysDept extends TreeEntity { +public class SysDept extends TenantEntity { @Serial private static final long serialVersionUID = 1L; @@ -33,6 +29,11 @@ public class SysDept extends TreeEntity { @TableId(value = "dept_id") private Long deptId; + /** + * 父部门ID + */ + private Long parentId; + /** * 部门名称 */ 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 index 14a9cf72d..ece40e3a2 100644 --- 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 @@ -3,7 +3,7 @@ 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.mybatis.core.domain.BaseEntity; +import com.ruoyi.common.tenant.core.TenantEntity; import lombok.Data; import lombok.EqualsAndHashCode; @@ -16,7 +16,7 @@ import lombok.EqualsAndHashCode; @Data @EqualsAndHashCode(callSuper = true) @TableName("sys_dict_data") -public class SysDictData extends BaseEntity { +public class SysDictData extends TenantEntity { /** * 字典编码 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 index bbab81226..96a1f285f 100644 --- 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 @@ -2,7 +2,7 @@ package com.ruoyi.system.domain; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import com.ruoyi.common.mybatis.core.domain.BaseEntity; +import com.ruoyi.common.tenant.core.TenantEntity; import lombok.Data; import lombok.EqualsAndHashCode; @@ -15,7 +15,7 @@ import lombok.EqualsAndHashCode; @Data @EqualsAndHashCode(callSuper = true) @TableName("sys_dict_type") -public class SysDictType extends BaseEntity { +public class SysDictType extends TenantEntity { /** * 字典主键 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 index 047936fa8..9ee8e621e 100644 --- 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 @@ -1,19 +1,12 @@ package com.ruoyi.system.domain; -import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; -import com.alibaba.excel.annotation.ExcelProperty; -import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import com.ruoyi.common.excel.annotation.ExcelDictFormat; -import com.ruoyi.common.excel.convert.ExcelDictConvert; import lombok.Data; import java.io.Serial; import java.io.Serializable; import java.util.Date; -import java.util.HashMap; -import java.util.Map; /** * 系统访问记录表 sys_logininfor @@ -23,7 +16,6 @@ import java.util.Map; @Data @TableName("sys_logininfor") -@ExcelIgnoreUnannotated public class SysLogininfor implements Serializable { @Serial @@ -32,63 +24,52 @@ public class SysLogininfor implements Serializable { /** * ID */ - @ExcelProperty(value = "序号") @TableId(value = "info_id") 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; - /** - * 请求参数 - */ - @TableField(exist = false) - private Map params = new HashMap<>(); - } 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 index 0ba4ab0d4..b02d74f7e 100644 --- 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 @@ -1,14 +1,18 @@ 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.TreeEntity; +import com.ruoyi.common.mybatis.core.domain.BaseEntity; import lombok.Data; import lombok.EqualsAndHashCode; +import java.util.ArrayList; +import java.util.List; + /** * 菜单权限表 sys_menu * @@ -18,7 +22,7 @@ import lombok.EqualsAndHashCode; @Data @EqualsAndHashCode(callSuper = true) @TableName("sys_menu") -public class SysMenu extends TreeEntity { +public class SysMenu extends BaseEntity { /** * 菜单ID @@ -26,6 +30,11 @@ public class SysMenu extends TreeEntity { @TableId(value = "menu_id") private Long menuId; + /** + * 父菜单ID + */ + private Long parentId; + /** * 菜单名称 */ @@ -91,6 +100,18 @@ public class SysMenu extends TreeEntity { */ private String remark; + /** + * 父菜单名称 + */ + @TableField(exist = false) + private String parentName; + + /** + * 子菜单 + */ + @TableField(exist = false) + private List children = new ArrayList<>(); + /** * 获取路由名称 */ 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 index 21fba9f0b..f61fd8c74 100644 --- 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 @@ -2,7 +2,7 @@ package com.ruoyi.system.domain; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import com.ruoyi.common.mybatis.core.domain.BaseEntity; +import com.ruoyi.common.tenant.core.TenantEntity; import lombok.Data; import lombok.EqualsAndHashCode; @@ -15,7 +15,7 @@ import lombok.EqualsAndHashCode; @Data @EqualsAndHashCode(callSuper = true) @TableName("sys_notice") -public class SysNotice extends BaseEntity { +public class SysNotice extends TenantEntity { /** * 公告ID 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 index 0486569ef..9cb3588ef 100644 --- 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 @@ -1,19 +1,12 @@ package com.ruoyi.system.domain; -import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; -import com.alibaba.excel.annotation.ExcelProperty; -import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import com.ruoyi.common.excel.annotation.ExcelDictFormat; -import com.ruoyi.common.excel.convert.ExcelDictConvert; import lombok.Data; import java.io.Serial; import java.io.Serializable; import java.util.Date; -import java.util.HashMap; -import java.util.Map; /** * 操作日志记录表 oper_log @@ -23,7 +16,6 @@ import java.util.Map; @Data @TableName("sys_oper_log") -@ExcelIgnoreUnannotated public class SysOperLog implements Serializable { @Serial @@ -32,113 +24,87 @@ public class SysOperLog implements Serializable { /** * 日志主键 */ - @ExcelProperty(value = "日志主键") @TableId(value = "oper_id") 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; - /** - * 业务类型数组 - */ - @TableField(exist = false) - 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正常 1异常) */ - @ExcelProperty(value = "状态", converter = ExcelDictConvert.class) - @ExcelDictFormat(dictType = "sys_common_status") private Integer status; /** * 错误消息 */ - @ExcelProperty(value = "错误消息") private String errorMsg; /** * 操作时间 */ - @ExcelProperty(value = "操作时间") private Date operTime; - /** - * 请求参数 - */ - @TableField(exist = false) - private Map params = new HashMap<>(); - } 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 index 31104a5c0..1f74be032 100644 --- 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 @@ -2,7 +2,7 @@ package com.ruoyi.system.domain; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import com.ruoyi.common.mybatis.core.domain.BaseEntity; +import com.ruoyi.common.tenant.core.TenantEntity; import lombok.Data; import lombok.EqualsAndHashCode; @@ -14,7 +14,7 @@ import lombok.EqualsAndHashCode; @Data @EqualsAndHashCode(callSuper = true) @TableName("sys_oss") -public class SysOss extends BaseEntity { +public class SysOss extends TenantEntity { /** * 对象存储主键 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 index 36b8293bd..8623f1aae 100644 --- 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 @@ -2,7 +2,7 @@ package com.ruoyi.system.domain; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import com.ruoyi.common.mybatis.core.domain.BaseEntity; +import com.ruoyi.common.tenant.core.TenantEntity; import lombok.Data; import lombok.EqualsAndHashCode; @@ -14,7 +14,7 @@ import lombok.EqualsAndHashCode; @Data @EqualsAndHashCode(callSuper = true) @TableName("sys_oss_config") -public class SysOssConfig extends BaseEntity { +public class SysOssConfig extends TenantEntity { /** * 主建 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 index 9da3cf527..970dd4d17 100644 --- 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 @@ -1,20 +1,11 @@ package com.ruoyi.system.domain; -import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; -import com.alibaba.excel.annotation.ExcelProperty; -import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import com.ruoyi.common.excel.annotation.ExcelDictFormat; -import com.ruoyi.common.excel.convert.ExcelDictConvert; -import com.ruoyi.common.mybatis.core.domain.BaseEntity; +import com.ruoyi.common.tenant.core.TenantEntity; import lombok.Data; import lombok.EqualsAndHashCode; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; - /** * 岗位表 sys_post * @@ -24,7 +15,7 @@ import jakarta.validation.constraints.Size; @Data @EqualsAndHashCode(callSuper = true) @TableName("sys_post") -public class SysPost extends BaseEntity { +public class SysPost extends TenantEntity { /** * 岗位序号 @@ -57,10 +48,4 @@ public class SysPost extends BaseEntity { */ private String remark; - /** - * 用户是否存在此岗位标识 默认不存在 - */ - @TableField(exist = false) - private boolean flag = false; - } 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 index 5c557cc22..f4d3f3093 100644 --- 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 @@ -1,16 +1,13 @@ package com.ruoyi.system.domain; -import com.baomidou.mybatisplus.annotation.TableField; 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 com.ruoyi.common.tenant.core.TenantEntity; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -import java.util.Set; - /** * 角色表 sys_role * @@ -21,7 +18,7 @@ import java.util.Set; @NoArgsConstructor @EqualsAndHashCode(callSuper = true) @TableName("sys_role") -public class SysRole extends BaseEntity { +public class SysRole extends TenantEntity { /** * 角色ID @@ -75,30 +72,6 @@ public class SysRole extends BaseEntity { */ private String remark; - /** - * 用户是否存在此角色标识 默认不存在 - */ - @TableField(exist = false) - private boolean flag = false; - - /** - * 菜单组 - */ - @TableField(exist = false) - private Long[] menuIds; - - /** - * 部门组(数据权限) - */ - @TableField(exist = false) - private Long[] deptIds; - - /** - * 角色菜单权限 - */ - @TableField(exist = false) - private Set permissions; - public SysRole(Long roleId) { this.roleId = roleId; } 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 new file mode 100644 index 000000000..e65fdf517 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTenant.java @@ -0,0 +1,103 @@ +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; + + /** + * 统一社会信用代码 + */ + 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正常 1停用) + */ + private String status; + + /** + * 删除标志(0代表存在 2代表删除) + */ + @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 new file mode 100644 index 000000000..c8ceef6a0 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTenantPackage.java @@ -0,0 +1,54 @@ +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正常 1停用) + */ + private String status; + /** + * 删除标志(0代表存在 2代表删除) + */ + @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 index 0338b376d..18e11c5d3 100644 --- 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 @@ -2,7 +2,7 @@ package com.ruoyi.system.domain; import com.baomidou.mybatisplus.annotation.*; import com.ruoyi.common.core.constant.UserConstants; -import com.ruoyi.common.mybatis.core.domain.BaseEntity; +import com.ruoyi.common.tenant.core.TenantEntity; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @@ -19,7 +19,7 @@ import java.util.Date; @NoArgsConstructor @EqualsAndHashCode(callSuper = true) @TableName("sys_user") -public class SysUser extends BaseEntity { +public class SysUser extends TenantEntity { /** * 用户ID @@ -108,7 +108,7 @@ public class SysUser extends BaseEntity { this.userId = userId; } - public boolean isAdmin() { + 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/SysDeptBo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysDeptBo.java index c66d066c2..11e9b0697 100644 --- 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 @@ -2,7 +2,7 @@ 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.TreeEntity; +import com.ruoyi.common.mybatis.core.domain.BaseEntity; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; @@ -18,7 +18,7 @@ import lombok.EqualsAndHashCode; @Data @EqualsAndHashCode(callSuper = true) -public class SysDeptBo extends TreeEntity { +public class SysDeptBo extends BaseEntity { /** * 部门id @@ -26,6 +26,11 @@ public class SysDeptBo extends TreeEntity { @NotNull(message = "部门id不能为空", groups = { EditGroup.class }) private Long deptId; + /** + * 父部门ID + */ + private Long parentId; + /** * 部门名称 */ @@ -37,7 +42,7 @@ public class SysDeptBo extends TreeEntity { * 显示顺序 */ @NotNull(message = "显示顺序不能为空") - private Long orderNum; + private Integer orderNum; /** * 负责人 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 new file mode 100644 index 000000000..4bbd35532 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysLogininforBo.java @@ -0,0 +1,74 @@ +package com.ruoyi.system.domain.bo; + +import lombok.Data; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * 系统访问记录业务对象 sys_logininfor + * + * @author Michelle.Chung + */ + +@Data +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 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 index a8b154393..909088682 100644 --- 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 @@ -3,7 +3,7 @@ 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.TreeEntity; +import com.ruoyi.common.mybatis.core.domain.BaseEntity; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; @@ -18,7 +18,7 @@ import lombok.EqualsAndHashCode; @Data @EqualsAndHashCode(callSuper = true) -public class SysMenuBo extends TreeEntity { +public class SysMenuBo extends BaseEntity { /** * 菜单ID @@ -26,6 +26,11 @@ public class SysMenuBo extends TreeEntity { @NotNull(message = "菜单ID不能为空", groups = { EditGroup.class }) private Long menuId; + /** + * 父菜单ID + */ + private Long parentId; + /** * 菜单名称 */ 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 new file mode 100644 index 000000000..443ff2b8e --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysOperLogBo.java @@ -0,0 +1,116 @@ +package com.ruoyi.system.domain.bo; + +import com.baomidou.mybatisplus.annotation.TableField; +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 +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正常 1异常) + */ + private Integer status; + + /** + * 错误消息 + */ + private String errorMsg; + + /** + * 操作时间 + */ + private Date operTime; + + /** + * 请求参数 + */ + @TableField(exist = false) + private Map 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 index b0e49ffe1..c6e058183 100644 --- 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 @@ -1,6 +1,7 @@ package com.ruoyi.system.domain.bo; import com.ruoyi.common.mybatis.core.domain.BaseEntity; +import com.ruoyi.common.tenant.core.TenantEntity; import lombok.Data; import lombok.EqualsAndHashCode; 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 index 50886f3c4..c089d9bb1 100644 --- 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 @@ -3,6 +3,7 @@ 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.common.tenant.core.TenantEntity; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; 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 index f0f96ad92..228153984 100644 --- 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 @@ -3,6 +3,7 @@ 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.common.tenant.core.TenantEntity; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; 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 index 64597572e..c9af4eddd 100644 --- 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 @@ -3,11 +3,12 @@ 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 jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import lombok.Data; import lombok.EqualsAndHashCode; -import jakarta.validation.constraints.*; - -import com.ruoyi.common.mybatis.core.domain.BaseEntity; import lombok.NoArgsConstructor; /** @@ -72,11 +73,21 @@ public class SysRoleBo extends BaseEntity { */ private String remark; + /** + * 菜单组 + */ + private Long[] menuIds; + + /** + * 部门组(数据权限) + */ + private Long[] deptIds; + public SysRoleBo(Long roleId) { this.roleId = roleId; } - public boolean isAdmin() { + 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 new file mode 100644 index 000000000..b9e97af1d --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysTenantBo.java @@ -0,0 +1,111 @@ +package com.ruoyi.system.domain.bo; + +import com.ruoyi.common.core.validate.AddGroup; +import com.ruoyi.common.core.validate.EditGroup; +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) +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; + + /** + * 统一社会信用代码 + */ + 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正常 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 new file mode 100644 index 000000000..b6a598962 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysTenantPackageBo.java @@ -0,0 +1,54 @@ +package com.ruoyi.system.domain.bo; + +import com.ruoyi.common.core.validate.AddGroup; +import com.ruoyi.common.core.validate.EditGroup; +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) +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 + */ + private Long[] menuIds; + + /** + * 备注 + */ + private String remark; + + /** + * 菜单树选择项是否关联显示 + */ + private Boolean menuCheckStrictly; + + /** + * 状态(0正常 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 index cd9dd4007..b3a92b53c 100644 --- 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 @@ -123,7 +123,7 @@ public class SysUserBo extends BaseEntity { this.userId = userId; } - public boolean isAdmin() { + 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/vo/SysDeptVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysDeptVo.java index 3ecba6295..8444444f7 100644 --- 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 @@ -52,7 +52,7 @@ public class SysDeptVo implements Serializable { /** * 显示顺序 */ - private Long orderNum; + private Integer orderNum; /** * 负责人 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 new file mode 100644 index 000000000..edd3fccf3 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysLogininforVo.java @@ -0,0 +1,90 @@ +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 lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + + + +/** + * 系统访问记录视图对象 sys_logininfor + * + * @author Michelle.Chung + * @date 2023-02-07 + */ +@Data +@ExcelIgnoreUnannotated +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/SysOperLogVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOperLogVo.java new file mode 100644 index 000000000..816198a3a --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysOperLogVo.java @@ -0,0 +1,138 @@ +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 lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + + +/** + * 操作日志记录视图对象 sys_oper_log + * + * @author Michelle.Chung + * @date 2023-02-07 + */ +@Data +@ExcelIgnoreUnannotated +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正常 1异常) + */ + @ExcelProperty(value = "状态", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "sys_common_status") + private Integer status; + + /** + * 错误消息 + */ + @ExcelProperty(value = "错误消息") + private String errorMsg; + + /** + * 操作时间 + */ + @ExcelProperty(value = "操作时间") + private Date operTime; + + +} 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 index 3e0414234..0bc71f245 100644 --- 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 @@ -10,7 +10,6 @@ import lombok.Data; import java.io.Serial; import java.io.Serializable; import java.util.Date; -import java.util.Set; /** * 角色信息视图对象 sys_role @@ -91,12 +90,7 @@ public class SysRoleVo implements Serializable { */ private boolean flag = false; - /** - * 角色菜单权限 - */ - private Set permissions; - - public boolean isAdmin() { + 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 new file mode 100644 index 000000000..d6888ba66 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysTenantPackageVo.java @@ -0,0 +1,63 @@ +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 lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + + +/** + * 租户套餐视图对象 sys_tenant_package + * + * @author Michelle.Chung + */ +@Data +@ExcelIgnoreUnannotated +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正常 1停用) + */ + @ExcelProperty(value = "状态", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "0=正常,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 new file mode 100644 index 000000000..51b573a5f --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysTenantVo.java @@ -0,0 +1,112 @@ +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 lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + + +/** + * 租户视图对象 sys_tenant + * + * @author Michelle.Chung + */ +@Data +@ExcelIgnoreUnannotated +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; + + /** + * 统一社会信用代码 + */ + @ExcelProperty(value = "统一社会信用代码") + 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正常 1停用) + */ + @ExcelProperty(value = "租户状态", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "0=正常,1=停用") + private String status; + + +} 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 index 90849b1d9..0de88f913 100644 --- 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 @@ -1,6 +1,5 @@ package com.ruoyi.system.domain.vo; -import com.ruoyi.common.core.constant.UserConstants; import com.ruoyi.common.translation.annotation.Translation; import com.ruoyi.common.translation.constant.TransConstant; import lombok.Data; @@ -27,6 +26,11 @@ public class SysUserVo implements Serializable { */ private Long userId; + /** + * 租户ID + */ + private String tenantId; + /** * 部门ID */ @@ -123,8 +127,4 @@ public class SysUserVo implements Serializable { */ private Long roleId; - public boolean isAdmin() { - return UserConstants.SUPER_ADMIN_ID.equals(this.userId); - } - } 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 index 06c6eff27..d21ef87bd 100644 --- 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 @@ -2,12 +2,13 @@ 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 { +public interface SysLogininforMapper extends BaseMapperPlus { } 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 index ae719ea25..81ea1df5d 100644 --- 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 @@ -2,12 +2,13 @@ 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 { +public interface SysOperLogMapper extends BaseMapperPlus { } 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 new file mode 100644 index 000000000..cc1e54f7d --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTenantMapper.java @@ -0,0 +1,14 @@ +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 { + +} 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 new file mode 100644 index 000000000..2f5731e4e --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTenantPackageMapper.java @@ -0,0 +1,14 @@ +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 { + +} 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 index 36ed651a0..e44cf8784 100644 --- 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 @@ -1,8 +1,5 @@ package com.ruoyi.system.runner; -import com.ruoyi.common.core.config.RuoYiConfig; -import com.ruoyi.system.service.ISysConfigService; -import com.ruoyi.system.service.ISysDictTypeService; import com.ruoyi.system.service.ISysOssConfigService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -20,22 +17,12 @@ import org.springframework.stereotype.Component; @Component public class SystemApplicationRunner implements ApplicationRunner { - private final RuoYiConfig ruoyiConfig; - private final ISysConfigService configService; - private final ISysDictTypeService dictTypeService; private final ISysOssConfigService ossConfigService; @Override public void run(ApplicationArguments args) throws Exception { ossConfigService.init(); log.info("初始化OSS配置成功"); - if (ruoyiConfig.isCacheLazy()) { - return; - } - configService.loadingConfigCache(); - log.info("加载参数缓存数据成功"); - dictTypeService.loadingDictCache(); - log.info("加载字典缓存数据成功"); } } 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 index a998500ad..af2ba2a4c 100644 --- 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 @@ -71,16 +71,6 @@ public interface ISysConfigService { */ void deleteConfigByIds(Long[] configIds); - /** - * 加载参数缓存数据 - */ - void loadingConfigCache(); - - /** - * 清空参数缓存数据 - */ - void clearConfigCache(); - /** * 重置参数缓存数据 */ 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 index 546e1bf00..e51c33e85 100644 --- 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 @@ -64,16 +64,6 @@ public interface ISysDictTypeService { */ void deleteDictTypeByIds(Long[] dictIds); - /** - * 加载字典缓存数据 - */ - void loadingDictCache(); - - /** - * 清空字典缓存数据 - */ - void clearDictCache(); - /** * 重置字典缓存数据 */ 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 index d67dfe4d0..4c5efc175 100644 --- 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 @@ -2,7 +2,8 @@ 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.SysLogininfor; +import com.ruoyi.system.domain.bo.SysLogininforBo; +import com.ruoyi.system.domain.vo.SysLogininforVo; import java.util.List; @@ -14,14 +15,14 @@ import java.util.List; public interface ISysLogininforService { - TableDataInfo selectPageLogininforList(SysLogininfor logininfor, PageQuery pageQuery); + TableDataInfo selectPageLogininforList(SysLogininforBo logininfor, PageQuery pageQuery); /** * 新增系统登录日志 * - * @param logininfor 访问日志对象 + * @param bo 访问日志对象 */ - void insertLogininfor(SysLogininfor logininfor); + void insertLogininfor(SysLogininforBo bo); /** * 查询系统登录日志集合 @@ -29,7 +30,7 @@ public interface ISysLogininforService { * @param logininfor 访问日志对象 * @return 登录记录集合 */ - List selectLogininforList(SysLogininfor logininfor); + List selectLogininforList(SysLogininforBo logininfor); /** * 批量删除系统登录日志 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 index 1a97b271b..4ca909ce9 100644 --- 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 @@ -65,6 +65,14 @@ public interface ISysMenuService { */ List selectMenuListByRoleId(Long roleId); + /** + * 根据租户套餐ID查询菜单树信息 + * + * @param packageId 租户套餐ID + * @return 选中菜单列表 + */ + List selectMenuListByPackageId(Long packageId); + /** * 构建前端路由所需要的菜单 * 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 index 72e4fe5bd..edce3a67e 100644 --- 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 @@ -2,7 +2,8 @@ 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.SysOperLog; +import com.ruoyi.system.domain.bo.SysOperLogBo; +import com.ruoyi.system.domain.vo.SysOperLogVo; import java.util.List; @@ -13,14 +14,14 @@ import java.util.List; */ public interface ISysOperLogService { - TableDataInfo selectPageOperLogList(SysOperLog operLog, PageQuery pageQuery); + TableDataInfo selectPageOperLogList(SysOperLogBo operLog, PageQuery pageQuery); /** * 新增操作日志 * - * @param operLog 操作日志对象 + * @param bo 操作日志对象 */ - void insertOperlog(SysOperLog operLog); + void insertOperlog(SysOperLogBo bo); /** * 查询系统操作日志集合 @@ -28,7 +29,7 @@ public interface ISysOperLogService { * @param operLog 操作日志对象 * @return 操作日志集合 */ - List selectOperLogList(SysOperLog operLog); + List selectOperLogList(SysOperLogBo operLog); /** * 批量删除系统操作日志 @@ -44,7 +45,7 @@ public interface ISysOperLogService { * @param operId 操作ID * @return 操作日志对象 */ - SysOperLog selectOperLogById(Long operId); + SysOperLogVo selectOperLogById(Long operId); /** * 清空操作日志 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 new file mode 100644 index 000000000..1e6d2d1db --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPermissionService.java @@ -0,0 +1,28 @@ +package com.ruoyi.system.service; + +import java.util.Set; + +/** + * 用户权限处理 + * + * @author Lion Li + */ +public interface ISysPermissionService { + + /** + * 获取角色数据权限 + * + * @param userId 用户id + * @return 角色权限信息 + */ + Set getRolePermission(Long userId); + + /** + * 获取菜单数据权限 + * + * @param userId 用户id + * @return 菜单权限信息 + */ + Set getMenuPermission(Long userId); + +} 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 new file mode 100644 index 000000000..629e89340 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTenantPackageService.java @@ -0,0 +1,52 @@ +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 queryPageList(SysTenantPackageBo bo, PageQuery pageQuery); + + /** + * 查询租户套餐列表 + */ + List queryList(SysTenantPackageBo bo); + + /** + * 新增租户套餐 + */ + Boolean insertByBo(SysTenantPackageBo bo); + + /** + * 修改租户套餐 + */ + Boolean updateByBo(SysTenantPackageBo bo); + + /** + * 修改套餐状态 + */ + int updatePackageStatus(SysTenantPackageBo bo); + + /** + * 校验并批量删除租户套餐信息 + */ + Boolean deleteWithValidByIds(Collection 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 new file mode 100644 index 000000000..ee7072550 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTenantService.java @@ -0,0 +1,72 @@ +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 queryPageList(SysTenantBo bo, PageQuery pageQuery); + + /** + * 查询租户列表 + */ + List queryList(SysTenantBo bo); + + /** + * 新增租户 + */ + Boolean insertByBo(SysTenantBo bo); + + /** + * 修改租户 + */ + Boolean updateByBo(SysTenantBo bo); + + /** + * 修改租户状态 + */ + int updateTenantStatus(SysTenantBo bo); + + /** + * 校验并批量删除租户信息 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 校验企业名称是否唯一 + */ + String checkCompanyNameUnique(SysTenantBo bo); + + /** + * 校验账号余额 + */ + String checkAccountBalance(String tenantId); + + /** + * 校验有效期 + */ + String checkExpireTime(String tenantId); +} 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 index dd9bccc48..b4b448940 100644 --- 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 @@ -133,7 +133,7 @@ public interface ISysUserService { * @param user 用户信息 * @return 结果 */ - boolean registerUser(SysUserBo user); + boolean registerUser(SysUserBo user, String tenantId); /** * 修改用户信息 diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/SysPermissionService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/SysPermissionService.java deleted file mode 100644 index c457bc00f..000000000 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/SysPermissionService.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.ruoyi.system.service; - -import cn.hutool.core.collection.CollUtil; -import com.ruoyi.system.domain.vo.SysRoleVo; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * 用户权限处理 - * - * @author ruoyi - */ -@RequiredArgsConstructor -@Service -public class SysPermissionService { - - private final ISysRoleService roleService; - private final ISysMenuService menuService; - - /** - * 获取角色数据权限 - * - * @param userId 用户id - * @param isAdmin 是否管理员 - * @return 角色权限信息 - */ - public Set getRolePermission(Long userId, boolean isAdmin) { - Set roles = new HashSet<>(); - // 管理员拥有所有权限 - if (isAdmin) { - roles.add("admin"); - } else { - roles.addAll(roleService.selectRolePermissionByUserId(userId)); - } - return roles; - } - - /** - * 获取菜单数据权限 - * - * @param userId 用户id - * @param isAdmin 是否管理员 - * @return 菜单权限信息 - */ - public Set getMenuPermission(Long userId, boolean isAdmin) { - Set perms = new HashSet<>(); - // 管理员拥有所有权限 - if (isAdmin) { - perms.add("*:*:*"); - } else { - List roles = roleService.selectRolesByUserId(userId); - if (CollUtil.isNotEmpty(roles)) { - // 多角色设置permissions属性,以便数据权限匹配权限 - for (SysRoleVo role : roles) { - Set rolePerms = menuService.selectMenuPermsByRoleId(role.getRoleId()); - role.setPermissions(rolePerms); - perms.addAll(rolePerms); - } - } else { - perms.addAll(menuService.selectMenuPermsByUserId(userId)); - } - } - return perms; - } -} 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 index 3104e1564..c70aa2291 100644 --- 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 @@ -9,13 +9,13 @@ 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.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.core.service.ConfigService; -import com.ruoyi.common.core.exception.ServiceException; -import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.redis.utils.CacheUtils; -import com.ruoyi.common.core.utils.SpringUtils; import com.ruoyi.system.domain.SysConfig; import com.ruoyi.system.domain.bo.SysConfigBo; import com.ruoyi.system.domain.vo.SysConfigVo; @@ -175,31 +175,12 @@ public class SysConfigServiceImpl implements ISysConfigService, ConfigService { baseMapper.deleteBatchIds(Arrays.asList(configIds)); } - /** - * 加载参数缓存数据 - */ - @Override - public void loadingConfigCache() { - List configsList = selectConfigList(new SysConfigBo()); - configsList.forEach(config -> - CacheUtils.put(CacheNames.SYS_CONFIG, config.getConfigKey(), config.getConfigValue())); - } - - /** - * 清空参数缓存数据 - */ - @Override - public void clearConfigCache() { - CacheUtils.clear(CacheNames.SYS_CONFIG); - } - /** * 重置参数缓存数据 */ @Override public void resetConfigCache() { - clearConfigCache(); - loadingConfigCache(); + CacheUtils.clear(CacheNames.SYS_CONFIG); } /** 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 index 453d98f70..fda7f62f8 100644 --- 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 @@ -142,13 +142,13 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService { @Override public String selectDeptNameByIds(String deptIds) { List list = new ArrayList<>(); - for (Long id : Arrays.stream(deptIds.split(",")).map(Long::parseLong).toList()) { + 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(",", list); + return String.join(StringUtils.SEPARATOR, list); } /** @@ -213,7 +213,7 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService { */ @Override public void checkDeptDataScope(Long deptId) { - if (!LoginHelper.isAdmin()) { + if (!LoginHelper.isSuperAdmin()) { SysDeptBo dept = new SysDeptBo(); dept.setDeptId(deptId); List depts = this.selectDeptList(dept); @@ -237,7 +237,7 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService { throw new ServiceException("部门停用,不允许新增"); } SysDept dept = BeanUtil.toBean(bo, SysDept.class); - dept.setAncestors(info.getAncestors() + "," + dept.getParentId()); + dept.setAncestors(info.getAncestors() + StringUtils.SEPARATOR + dept.getParentId()); return baseMapper.insert(dept); } @@ -254,7 +254,7 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService { SysDept newParentDept = baseMapper.selectById(dept.getParentId()); SysDept oldDept = baseMapper.selectById(dept.getDeptId()); if (ObjectUtil.isNotNull(newParentDept) && ObjectUtil.isNotNull(oldDept)) { - String newAncestors = newParentDept.getAncestors() + "," + newParentDept.getDeptId(); + String newAncestors = newParentDept.getAncestors() + StringUtils.SEPARATOR + newParentDept.getDeptId(); String oldAncestors = oldDept.getAncestors(); dept.setAncestors(newAncestors); updateDeptChildren(dept.getDeptId(), newAncestors, oldAncestors); 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 index aae31591d..8fb48f96d 100644 --- 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 @@ -11,16 +11,16 @@ 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.constant.UserConstants; -import com.ruoyi.common.mybatis.core.page.PageQuery; -import com.ruoyi.common.core.service.DictService; -import com.ruoyi.system.domain.SysDictData; -import com.ruoyi.system.domain.SysDictType; -import com.ruoyi.common.mybatis.core.page.TableDataInfo; import com.ruoyi.common.core.exception.ServiceException; +import com.ruoyi.common.core.service.DictService; +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.common.core.utils.SpringUtils; +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; @@ -33,7 +33,10 @@ import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; import java.util.stream.Collectors; /** @@ -145,35 +148,12 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService baseMapper.deleteBatchIds(Arrays.asList(dictIds)); } - /** - * 加载字典缓存数据 - */ - @Override - public void loadingDictCache() { - List dictDataList = dictDataMapper.selectVoList( - new LambdaQueryWrapper().eq(SysDictData::getStatus, UserConstants.DICT_NORMAL)); - Map> dictDataMap = StreamUtils.groupByKey(dictDataList, SysDictDataVo::getDictType); - dictDataMap.forEach((k,v) -> { - List dictList = StreamUtils.sorted(v, Comparator.comparing(SysDictDataVo::getDictSort)); - CacheUtils.put(CacheNames.SYS_DICT, k, dictList); - }); - } - - /** - * 清空字典缓存数据 - */ - @Override - public void clearDictCache() { - CacheUtils.clear(CacheNames.SYS_DICT); - } - /** * 重置字典缓存数据 */ @Override public void resetDictCache() { - clearDictCache(); - loadingDictCache(); + CacheUtils.clear(CacheNames.SYS_DICT); } /** 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 index 492dd1c82..c8306624c 100644 --- 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 @@ -1,5 +1,6 @@ package com.ruoyi.system.service.impl; +import cn.hutool.core.bean.BeanUtil; import cn.hutool.http.useragent.UserAgent; import cn.hutool.http.useragent.UserAgentUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -12,6 +13,8 @@ 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; @@ -64,7 +67,8 @@ public class SysLogininforServiceImpl implements ISysLogininforService { // 获取客户端浏览器 String browser = userAgent.getBrowser().getName(); // 封装对象 - SysLogininfor logininfor = new SysLogininfor(); + SysLogininforBo logininfor = new SysLogininforBo(); + logininfor.setTenantId(logininforEvent.getTenantId()); logininfor.setUserName(logininforEvent.getUsername()); logininfor.setIpaddr(ip); logininfor.setLoginLocation(address); @@ -89,7 +93,7 @@ public class SysLogininforServiceImpl implements ISysLogininforService { } @Override - public TableDataInfo selectPageLogininforList(SysLogininfor logininfor, PageQuery pageQuery) { + public TableDataInfo selectPageLogininforList(SysLogininforBo logininfor, PageQuery pageQuery) { Map params = logininfor.getParams(); LambdaQueryWrapper lqw = new LambdaQueryWrapper() .like(StringUtils.isNotBlank(logininfor.getIpaddr()), SysLogininfor::getIpaddr, logininfor.getIpaddr()) @@ -101,17 +105,18 @@ public class SysLogininforServiceImpl implements ISysLogininforService { pageQuery.setOrderByColumn("info_id"); pageQuery.setIsAsc("desc"); } - Page page = baseMapper.selectPage(pageQuery.build(), lqw); + Page page = baseMapper.selectVoPage(pageQuery.build(), lqw); return TableDataInfo.build(page); } /** * 新增系统登录日志 * - * @param logininfor 访问日志对象 + * @param bo 访问日志对象 */ @Override - public void insertLogininfor(SysLogininfor logininfor) { + public void insertLogininfor(SysLogininforBo bo) { + SysLogininfor logininfor = BeanUtil.toBean(bo, SysLogininfor.class); logininfor.setLoginTime(new Date()); baseMapper.insert(logininfor); } @@ -123,9 +128,9 @@ public class SysLogininforServiceImpl implements ISysLogininforService { * @return 登录记录集合 */ @Override - public List selectLogininforList(SysLogininfor logininfor) { + public List selectLogininforList(SysLogininforBo logininfor) { Map params = logininfor.getParams(); - return baseMapper.selectList(new LambdaQueryWrapper() + return baseMapper.selectVoList(new LambdaQueryWrapper() .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()) 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 index ca941510f..29cdcb5b6 100644 --- 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 @@ -2,6 +2,7 @@ package com.ruoyi.system.service.impl; import cn.hutool.core.bean.BeanUtil; 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; @@ -16,6 +17,7 @@ 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; @@ -23,6 +25,7 @@ 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; @@ -41,6 +44,7 @@ public class SysMenuServiceImpl implements ISysMenuService { private final SysMenuMapper baseMapper; private final SysRoleMapper roleMapper; private final SysRoleMenuMapper roleMenuMapper; + private final SysTenantPackageMapper sysTenantPackageMapper; /** * 根据用户查询系统菜单列表 @@ -63,7 +67,7 @@ public class SysMenuServiceImpl implements ISysMenuService { public List selectMenuList(SysMenuBo menu, Long userId) { List menuList; // 管理员显示所有菜单信息 - if (LoginHelper.isAdmin(userId)) { + if (LoginHelper.isSuperAdmin(userId)) { menuList = baseMapper.selectVoList(new LambdaQueryWrapper() .like(StringUtils.isNotBlank(menu.getMenuName()), SysMenu::getMenuName, menu.getMenuName()) .eq(StringUtils.isNotBlank(menu.getVisible()), SysMenu::getVisible, menu.getVisible()) @@ -96,7 +100,7 @@ public class SysMenuServiceImpl implements ISysMenuService { Set permsSet = new HashSet<>(); for (String perm : perms) { if (StringUtils.isNotEmpty(perm)) { - permsSet.addAll(Arrays.asList(perm.trim().split(","))); + permsSet.addAll(StringUtils.splitList(perm.trim())); } } return permsSet; @@ -114,7 +118,7 @@ public class SysMenuServiceImpl implements ISysMenuService { Set permsSet = new HashSet<>(); for (String perm : perms) { if (StringUtils.isNotEmpty(perm)) { - permsSet.addAll(Arrays.asList(perm.trim().split(","))); + permsSet.addAll(StringUtils.splitList(perm.trim())); } } return permsSet; @@ -129,7 +133,7 @@ public class SysMenuServiceImpl implements ISysMenuService { @Override public List selectMenuTreeByUserId(Long userId) { List menus; - if (LoginHelper.isAdmin(userId)) { + if (LoginHelper.isSuperAdmin(userId)) { menus = baseMapper.selectMenuTreeAll(); } else { menus = baseMapper.selectMenuTreeByUserId(userId); @@ -149,6 +153,30 @@ public class SysMenuServiceImpl implements ISysMenuService { return baseMapper.selectMenuListByRoleId(roleId, role.getMenuCheckStrictly()); } + /** + * 根据租户套餐ID查询菜单树信息 + * + * @param packageId 租户套餐ID + * @return 选中菜单列表 + */ + @Override + public List selectMenuListByPackageId(Long packageId) { + SysTenantPackage tenantPackage = sysTenantPackageMapper.selectById(packageId); + List menuIds = StringUtils.splitTo(tenantPackage.getMenuIds(), Convert::toLong); + if (CollUtil.isEmpty(menuIds)) { + return List.of(); + } + List parentIds = null; + if (tenantPackage.getMenuCheckStrictly()) { + parentIds = baseMapper.selectObjs(new LambdaQueryWrapper() + .select(SysMenu::getParentId) + .in(SysMenu::getMenuId, menuIds), Convert::toLong); + } + return baseMapper.selectObjs(new LambdaQueryWrapper() + .in(SysMenu::getMenuId, menuIds) + .notIn(CollUtil.isNotEmpty(parentIds), SysMenu::getMenuId, parentIds), Convert::toLong); + } + /** * 构建前端路由所需要的菜单 * 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 index 2d89d773c..671a35083 100644 --- 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 @@ -10,6 +10,8 @@ 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; @@ -41,14 +43,14 @@ public class SysOperLogServiceImpl implements ISysOperLogService { @Async @EventListener public void recordOper(OperLogEvent operLogEvent) { - SysOperLog operLog = BeanUtil.toBean(operLogEvent, SysOperLog.class); + SysOperLogBo operLog = BeanUtil.toBean(operLogEvent, SysOperLogBo.class); // 远程查询操作地点 operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp())); insertOperlog(operLog); } @Override - public TableDataInfo selectPageOperLogList(SysOperLog operLog, PageQuery pageQuery) { + public TableDataInfo selectPageOperLogList(SysOperLogBo operLog, PageQuery pageQuery) { Map params = operLog.getParams(); LambdaQueryWrapper lqw = new LambdaQueryWrapper() .like(StringUtils.isNotBlank(operLog.getTitle()), SysOperLog::getTitle, operLog.getTitle()) @@ -68,17 +70,18 @@ public class SysOperLogServiceImpl implements ISysOperLogService { pageQuery.setOrderByColumn("oper_id"); pageQuery.setIsAsc("desc"); } - Page page = baseMapper.selectPage(pageQuery.build(), lqw); + Page page = baseMapper.selectVoPage(pageQuery.build(), lqw); return TableDataInfo.build(page); } /** * 新增操作日志 * - * @param operLog 操作日志对象 + * @param bo 操作日志对象 */ @Override - public void insertOperlog(SysOperLog operLog) { + public void insertOperlog(SysOperLogBo bo) { + SysOperLog operLog = BeanUtil.toBean(bo, SysOperLog.class); operLog.setOperTime(new Date()); baseMapper.insert(operLog); } @@ -90,9 +93,9 @@ public class SysOperLogServiceImpl implements ISysOperLogService { * @return 操作日志集合 */ @Override - public List selectOperLogList(SysOperLog operLog) { + public List selectOperLogList(SysOperLogBo operLog) { Map params = operLog.getParams(); - return baseMapper.selectList(new LambdaQueryWrapper() + return baseMapper.selectVoList(new LambdaQueryWrapper() .like(StringUtils.isNotBlank(operLog.getTitle()), SysOperLog::getTitle, operLog.getTitle()) .eq(operLog.getBusinessType() != null && operLog.getBusinessType() > 0, SysOperLog::getBusinessType, operLog.getBusinessType()) @@ -127,8 +130,8 @@ public class SysOperLogServiceImpl implements ISysOperLogService { * @return 操作日志对象 */ @Override - public SysOperLog selectOperLogById(Long operId) { - return baseMapper.selectById(operId); + public SysOperLogVo selectOperLogById(Long operId) { + return baseMapper.selectVoById(operId); } /** 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 index fe97a9eff..61e5c8d0f 100644 --- 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 @@ -10,15 +10,16 @@ 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.utils.SpringUtils; +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.oss.factory.OssFactory; 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; @@ -26,12 +27,12 @@ import com.ruoyi.system.mapper.SysOssConfigMapper; import com.ruoyi.system.service.ISysOssConfigService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.Collection; import java.util.List; +import java.util.Map; /** * 对象存储配置Service业务层处理 @@ -52,17 +53,23 @@ public class SysOssConfigServiceImpl implements ISysOssConfigService { */ @Override public void init() { - List list = baseMapper.selectList(); - // 加载OSS初始化配置 - for (SysOssConfig config : list) { - String configKey = config.getConfigKey(); - if ("0".equals(config.getStatus())) { - RedisUtils.setCacheObject(OssConstant.DEFAULT_CONFIG_KEY, configKey); + TenantHelper.enableIgnore(); + List list = baseMapper.selectList( + new LambdaQueryWrapper().orderByAsc(TenantEntity::getTenantId)); + TenantHelper.disableIgnore(); + Map> 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)); } - SpringUtils.context().publishEvent(config); } - // 初始化OSS工厂 - OssFactory.init(); + TenantHelper.clearDynamic(); } @Override @@ -92,7 +99,7 @@ public class SysOssConfigServiceImpl implements ISysOssConfigService { validEntityBeforeSave(config); boolean flag = baseMapper.insert(config) > 0; if (flag) { - SpringUtils.context().publishEvent(config); + CacheUtils.put(CacheNames.SYS_OSS_CONFIG, config.getConfigKey(), JsonUtils.toJsonString(config)); } return flag; } @@ -109,7 +116,7 @@ public class SysOssConfigServiceImpl implements ISysOssConfigService { luw.eq(SysOssConfig::getOssConfigId, config.getOssConfigId()); boolean flag = baseMapper.update(config, luw) > 0; if (flag) { - SpringUtils.context().publishEvent(config); + CacheUtils.put(CacheNames.SYS_OSS_CONFIG, config.getConfigKey(), JsonUtils.toJsonString(config)); } return flag; } @@ -174,16 +181,4 @@ public class SysOssConfigServiceImpl implements ISysOssConfigService { return row; } - /** - * 更新配置缓存 - * - * @param config 配置 - */ - @EventListener - public void updateConfigCache(SysOssConfig config) { - CacheUtils.put(CacheNames.SYS_OSS_CONFIG, config.getConfigKey(), JsonUtils.toJsonString(config)); - RedisUtils.publish(OssConstant.DEFAULT_CONFIG_KEY, config.getConfigKey(), msg -> { - log.info("发布刷新OSS配置 => " + msg); - }); - } } 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 index db3b6c91e..21d7dd139 100644 --- 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 @@ -1,5 +1,6 @@ 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; @@ -70,13 +71,13 @@ public class SysOssServiceImpl implements ISysOssService, OssService { @Override public String selectUrlByIds(String ossIds) { List list = new ArrayList<>(); - for (Long id : Arrays.stream(ossIds.split(",")).map(Long::parseLong).toList()) { + 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(",", list); + return String.join(StringUtils.SEPARATOR, list); } private LambdaQueryWrapper buildQueryWrapper(SysOssBo bo) { 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 new file mode 100644 index 000000000..ded956c56 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPermissionServiceImpl.java @@ -0,0 +1,61 @@ +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 getRolePermission(Long userId) { + Set 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 getMenuPermission(Long userId) { + Set 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/SysRoleServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java index e83a124d0..a04f81fe3 100644 --- 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 @@ -6,11 +6,11 @@ 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.toolkit.StringUtils; 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.utils.StreamUtils; +import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.mybatis.core.page.PageQuery; import com.ruoyi.system.domain.SysRole; import com.ruoyi.common.mybatis.core.page.TableDataInfo; @@ -110,7 +110,7 @@ public class SysRoleServiceImpl implements ISysRoleService { Set permsSet = new HashSet<>(); for (SysRoleVo perm : perms) { if (ObjectUtil.isNotNull(perm)) { - permsSet.addAll(Arrays.asList(perm.getRoleKey().trim().split(","))); + permsSet.addAll(StringUtils.splitList(perm.getRoleKey().trim())); } } return permsSet; @@ -189,7 +189,7 @@ public class SysRoleServiceImpl implements ISysRoleService { */ @Override public void checkRoleAllowed(SysRoleBo role) { - if (ObjectUtil.isNotNull(role.getRoleId()) && role.isAdmin()) { + if (ObjectUtil.isNotNull(role.getRoleId()) && role.isSuperAdmin()) { throw new ServiceException("不允许操作超级管理员角色"); } } @@ -201,7 +201,7 @@ public class SysRoleServiceImpl implements ISysRoleService { */ @Override public void checkRoleDataScope(Long roleId) { - if (!LoginHelper.isAdmin()) { + if (!LoginHelper.isSuperAdmin()) { SysRoleBo role = new SysRoleBo(); role.setRoleId(roleId); List roles = this.selectRoleList(role); @@ -234,7 +234,7 @@ public class SysRoleServiceImpl implements ISysRoleService { SysRole role = BeanUtil.toBean(bo, SysRole.class); // 新增角色信息 baseMapper.insert(role); - return insertRoleMenu(role); + return insertRoleMenu(bo); } /** @@ -251,7 +251,7 @@ public class SysRoleServiceImpl implements ISysRoleService { baseMapper.updateById(role); // 删除角色与菜单关联 roleMenuMapper.delete(new LambdaQueryWrapper().eq(SysRoleMenu::getRoleId, role.getRoleId())); - return insertRoleMenu(role); + return insertRoleMenu(bo); } /** @@ -281,7 +281,7 @@ public class SysRoleServiceImpl implements ISysRoleService { // 删除角色与部门关联 roleDeptMapper.delete(new LambdaQueryWrapper().eq(SysRoleDept::getRoleId, role.getRoleId())); // 新增角色和部门信息(数据权限) - return insertRoleDept(role); + return insertRoleDept(bo); } /** @@ -289,7 +289,7 @@ public class SysRoleServiceImpl implements ISysRoleService { * * @param role 角色对象 */ - public int insertRoleMenu(SysRole role) { + public int insertRoleMenu(SysRoleBo role) { int rows = 1; // 新增用户与角色管理 List list = new ArrayList(); @@ -310,7 +310,7 @@ public class SysRoleServiceImpl implements ISysRoleService { * * @param role 角色对象 */ - public int insertRoleDept(SysRole role) { + public int insertRoleDept(SysRoleBo role) { int rows = 1; // 新增角色与部门(数据权限)管理 List list = new ArrayList(); 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 index 40123c73e..cab1f4c33 100644 --- 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 @@ -20,7 +20,7 @@ public class SysSensitiveServiceImpl implements SensitiveService { */ @Override public boolean isSensitive() { - return !LoginHelper.isAdmin(); + 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 new file mode 100644 index 000000000..211c22851 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTenantPackageServiceImpl.java @@ -0,0 +1,139 @@ +package com.ruoyi.system.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import com.ruoyi.common.core.exception.ServiceException; +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 queryPageList(SysTenantPackageBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询租户套餐列表 + */ + @Override + public List queryList(SysTenantPackageBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(SysTenantPackageBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper 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 = BeanUtil.toBean(bo, SysTenantPackage.class); + // 保存菜单id + List 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 = BeanUtil.toBean(bo, SysTenantPackage.class); + // 保存菜单id + List 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 = BeanUtil.toBean(bo, SysTenantPackage.class); + return baseMapper.updateById(tenantPackage); + } + + /** + * 批量删除租户套餐 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + boolean exists = tenantMapper.exists(new LambdaQueryWrapper().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 new file mode 100644 index 000000000..e22f651f7 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTenantServiceImpl.java @@ -0,0 +1,334 @@ +package com.ruoyi.system.service.impl; + +import cn.dev33.satoken.secure.BCrypt; +import cn.hutool.core.bean.BeanUtil; +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.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 sysTenantPackageMapper; + private final SysUserMapper sysUserMapper; + private final SysDeptMapper sysDeptMapper; + private final SysRoleMapper sysRoleMapper; + private final SysRoleMenuMapper sysRoleMenuMapper; + private final SysRoleDeptMapper sysRoleDeptMapper; + private final SysUserRoleMapper sysUserRoleMapper; + private final SysDictTypeMapper sysDictTypeMapper; + private final SysDictDataMapper sysDictDataMapper; + private final SysConfigMapper sysConfigMapper; + + /** + * 查询租户 + */ + @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().eq(SysTenant::getTenantId, tenantId)); + } + + /** + * 查询租户列表 + */ + @Override + public TableDataInfo queryPageList(SysTenantBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询租户列表 + */ + @Override + public List queryList(SysTenantBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(SysTenantBo bo) { + LambdaQueryWrapper 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 = BeanUtil.toBean(bo, SysTenant.class); + + // 获取所有租户编号 + List tenantIds = baseMapper.selectObjs( + new LambdaQueryWrapper().select(SysTenant::getTenantId), Convert::toStr); + String tenantId = generateTenantId(tenantIds); + add.setTenantId(tenantId); + boolean flag = baseMapper.insert(add) > 0; + if (!flag) { + 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()); + sysDeptMapper.insert(dept); + Long deptId = dept.getDeptId(); + + // 角色和部门关联表 + SysRoleDept roleDept = new SysRoleDept(); + roleDept.setRoleId(roleId); + roleDept.setDeptId(deptId); + sysRoleDeptMapper.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); + sysUserMapper.insert(user); + + // 用户和角色关联表 + SysUserRole userRole = new SysUserRole(); + userRole.setUserId(user.getUserId()); + userRole.setRoleId(roleId); + sysUserRoleMapper.insert(userRole); + + String defaultTenantId = TenantConstants.DEFAULT_TENANT_ID; + List dictTypeList = sysDictTypeMapper.selectList( + new LambdaQueryWrapper().eq(SysDictType::getTenantId, defaultTenantId)); + List dictDataList = sysDictDataMapper.selectList( + new LambdaQueryWrapper().eq(SysDictData::getTenantId, defaultTenantId)); + for (SysDictType dictType : dictTypeList) { + dictType.setDictId(null); + dictType.setTenantId(tenantId); + } + for (SysDictData dictData : dictDataList) { + dictData.setDictCode(null); + dictData.setTenantId(tenantId); + } + sysDictTypeMapper.insertBatch(dictTypeList); + sysDictDataMapper.insertBatch(dictDataList); + + List sysConfigList = sysConfigMapper.selectList( + new LambdaQueryWrapper().eq(SysConfig::getTenantId, defaultTenantId)); + for (SysConfig config : sysConfigList) { + config.setConfigId(null); + config.setTenantId(tenantId); + } + sysConfigMapper.insertBatch(sysConfigList); + + TenantHelper.disableIgnore(); + return true; + } + + /** + * 生成租户id + * + * @param tenantIds 已有租户id列表 + * @return 租户id + */ + private String generateTenantId(List tenantIds) { + // 随机生成6位 + String numbers = RandomUtil.randomNumbers(6); + // 判断是否存在,如果存在则重新生成 + if (tenantIds.contains(numbers)) { + generateTenantId(tenantIds); + } + return numbers; + } + + /** + * 根据租户菜单创建租户角色 + * + * @param tenantId 租户编号 + * @param packageId 租户套餐id + * @return 角色id + */ + public Long createTenantRole(String tenantId, Long packageId) { + // 获取租户套餐 + SysTenantPackage tenantPackage = sysTenantPackageMapper.selectById(packageId); + if (ObjectUtil.isNull(tenantPackage)) { + throw new ServiceException("套餐不存在"); + } + // 获取套餐菜单id + List 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); + sysRoleMapper.insert(role); + Long roleId = role.getRoleId(); + + // 创建角色菜单 + List roleMenus = new ArrayList<>(menuIds.size()); + menuIds.forEach(menuId -> { + SysRoleMenu roleMenu = new SysRoleMenu(); + roleMenu.setRoleId(roleId); + roleMenu.setMenuId(menuId); + roleMenus.add(roleMenu); + }); + sysRoleMenuMapper.insertBatch(roleMenus); + + return roleId; + } + + /** + * 修改租户 + */ + @CacheEvict(cacheNames = CacheNames.SYS_TENANT, key = "#bo.tenantId") + @Override + public Boolean updateByBo(SysTenantBo bo) { + SysTenant tenant = BeanUtil.toBean(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 = BeanUtil.toBean(bo, SysTenant.class); + return baseMapper.updateById(tenant); + } + + /** + * 批量删除租户 + */ + @CacheEvict(cacheNames = CacheNames.SYS_TENANT, allEntries = true) + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if (isValid) { + // 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteBatchIds(ids) > 0; + } + + /** + * 校验企业名称是否唯一 + */ + @Override + public String checkCompanyNameUnique(SysTenantBo bo) { + boolean exist = baseMapper.exists(new LambdaQueryWrapper() + .eq(SysTenant::getCompanyName, bo.getCompanyName()) + .ne(ObjectUtil.isNotNull(bo.getTenantId()), SysTenant::getTenantId, bo.getTenantId())); + if (exist) { + return TenantConstants.NOT_PASS; + } + return TenantConstants.PASS; + } + + /** + * 校验账号余额 + */ + @Override + public String checkAccountBalance(String tenantId) { + SysTenantVo tenant = SpringUtils.getAopProxy(this).queryByTenantId(tenantId); + // 如果余额为-1代表不限制 + if (tenant.getAccountCount() == -1) { + return TenantConstants.PASS; + } + Long userNumber = sysUserMapper.selectCount(new LambdaQueryWrapper<>()); + // 如果余额大于0代表还有可用名额 + if (tenant.getAccountCount() - userNumber > 0) { + return TenantConstants.PASS; + } + return TenantConstants.NOT_PASS; + } + + /** + * 校验有效期 + */ + @Override + public String checkExpireTime(String tenantId) { + SysTenantVo tenant = SpringUtils.getAopProxy(this).queryByTenantId(tenantId); + // 如果未设置过期时间代表不限制 + if (ObjectUtil.isNull(tenant.getExpireTime())) { + return TenantConstants.PASS; + } + // 如果当前时间在过期时间之前则通过 + if (new Date().before(tenant.getExpireTime())) { + return TenantConstants.PASS; + } + return TenantConstants.NOT_PASS; + } + +} 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 index ee36fe536..1628d5fcc 100644 --- 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 @@ -250,7 +250,7 @@ public class SysUserServiceImpl implements ISysUserService, UserService { */ @Override public void checkUserAllowed(SysUserBo user) { - if (ObjectUtil.isNotNull(user.getUserId()) && user.isAdmin()) { + if (ObjectUtil.isNotNull(user.getUserId()) && user.isSuperAdmin()) { throw new ServiceException("不允许操作超级管理员用户"); } } @@ -262,7 +262,7 @@ public class SysUserServiceImpl implements ISysUserService, UserService { */ @Override public void checkUserDataScope(Long userId) { - if (!LoginHelper.isAdmin()) { + if (!LoginHelper.isSuperAdmin()) { SysUserBo user = new SysUserBo(); user.setUserId(userId); List users = this.selectUserList(user); @@ -298,10 +298,11 @@ public class SysUserServiceImpl implements ISysUserService, UserService { * @return 结果 */ @Override - public boolean registerUser(SysUserBo user) { + public boolean registerUser(SysUserBo user, String tenantId) { user.setCreateBy(user.getUserId()); user.setUpdateBy(user.getUserId()); SysUser sysUser = BeanUtil.copyProperties(user, SysUser.class); + sysUser.setTenantId(tenantId); return baseMapper.insert(sysUser) > 0; } 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 new file mode 100644 index 000000000..f3fa4cb1b --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysTenantMapper.xml @@ -0,0 +1,7 @@ + + + + + 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 new file mode 100644 index 000000000..23b46dfcd --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysTenantPackageMapper.xml @@ -0,0 +1,7 @@ + + + + + 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 b6ba60108..74e41b99a 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 @@ -22,6 +22,7 @@ select u.user_id, + u.tenant_id, u.dept_id, u.user_name, u.nick_name, diff --git a/ruoyi-ui/src/api/login.js b/ruoyi-ui/src/api/login.js index 3c5bcfe21..6b8d85703 100644 --- a/ruoyi-ui/src/api/login.js +++ b/ruoyi-ui/src/api/login.js @@ -1,8 +1,9 @@ import request from '@/utils/request' // 登录方法 -export function login(username, password, code, uuid) { +export function login(tenantId, username, password, code, uuid) { const data = { + tenantId, username, password, code, @@ -69,3 +70,14 @@ export function getCodeSms() { timeout: 20000 }) } + +// 获取租户列表 +export function tenantList() { + return request({ + url: '/tenant/list', + headers: { + isToken: false + }, + method: 'get' + }) +} diff --git a/ruoyi-ui/src/api/system/menu.js b/ruoyi-ui/src/api/system/menu.js index f6415c656..b23352586 100644 --- a/ruoyi-ui/src/api/system/menu.js +++ b/ruoyi-ui/src/api/system/menu.js @@ -33,6 +33,14 @@ export function roleMenuTreeselect(roleId) { }) } +// 根据角色ID查询菜单下拉树结构 +export function tenantPackageMenuTreeselect(packageId) { + return request({ + url: '/system/menu/tenantPackageMenuTreeselect/' + packageId, + method: 'get' + }) +} + // 新增菜单 export function addMenu(data) { return request({ @@ -57,4 +65,4 @@ export function delMenu(menuId) { url: '/system/menu/' + menuId, method: 'delete' }) -} \ No newline at end of file +} diff --git a/ruoyi-ui/src/api/system/tenant.js b/ruoyi-ui/src/api/system/tenant.js new file mode 100644 index 000000000..76ca9ff91 --- /dev/null +++ b/ruoyi-ui/src/api/system/tenant.js @@ -0,0 +1,74 @@ +import request from '@/utils/request' + +// 查询租户列表 +export function listTenant(query) { + return request({ + url: '/system/tenant/list', + method: 'get', + params: query + }) +} + +// 查询租户详细 +export function getTenant(id) { + return request({ + url: '/system/tenant/' + id, + method: 'get' + }) +} + +// 新增租户 +export function addTenant(data) { + return request({ + url: '/system/tenant', + method: 'post', + data: data + }) +} + +// 修改租户 +export function updateTenant(data) { + return request({ + url: '/system/tenant', + method: 'put', + data: data + }) +} + +// 租户状态修改 +export function changeTenantStatus(id, status) { + const data = { + id, + status + } + return request({ + url: '/system/tenant/changeStatus', + method: 'put', + data: data + }) +} + +// 删除租户 +export function delTenant(id) { + return request({ + url: '/system/tenant/' + id, + method: 'delete' + }) +} + +// 动态切换租户 +export function dynamicTenant(tenantId) { + return request({ + url: '/system/tenant/dynamic/' + tenantId, + method: 'get' + }) +} + +// 清除动态租户 +export function dynamicClear() { + return request({ + url: '/system/tenant/dynamic/clear', + method: 'get' + }) +} + diff --git a/ruoyi-ui/src/api/system/tenantPackage.js b/ruoyi-ui/src/api/system/tenantPackage.js new file mode 100644 index 000000000..91ac8f857 --- /dev/null +++ b/ruoyi-ui/src/api/system/tenantPackage.js @@ -0,0 +1,58 @@ +import request from '@/utils/request' + +// 查询租户套餐列表 +export function listTenantPackage(query) { + return request({ + url: '/system/tenant/package/list', + method: 'get', + params: query + }) +} + +// 查询租户套餐详细 +export function getTenantPackage(packageId) { + return request({ + url: '/system/tenant/package/' + packageId, + method: 'get' + }) +} + +// 新增租户套餐 +export function addTenantPackage(data) { + return request({ + url: '/system/tenant/package', + method: 'post', + data: data + }) +} + +// 修改租户套餐 +export function updateTenantPackage(data) { + return request({ + url: '/system/tenant/package', + method: 'put', + data: data + }) +} + +// 租户套餐状态修改 +export function changePackageStatus(packageId, status) { + const data = { + packageId, + status + } + return request({ + url: '/system/tenant/package/changeStatus', + method: 'put', + data: data + }) +} + + +// 删除租户套餐 +export function delTenantPackage(packageId) { + return request({ + url: '/system/tenant/package/' + packageId, + method: 'delete' + }) +} diff --git a/ruoyi-ui/src/assets/icons/svg/company.svg b/ruoyi-ui/src/assets/icons/svg/company.svg new file mode 100644 index 000000000..fcf139410 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/company.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ruoyi-ui/src/layout/components/Navbar.vue b/ruoyi-ui/src/layout/components/Navbar.vue index 9de102c16..85fb1b582 100644 --- a/ruoyi-ui/src/layout/components/Navbar.vue +++ b/ruoyi-ui/src/layout/components/Navbar.vue @@ -5,8 +5,25 @@ -
-