From 84b2c39a303a3423f4114c7bb59fe1de62414cab Mon Sep 17 00:00:00 2001 From: Charles7c Date: Sun, 20 Jul 2025 23:13:07 +0800 Subject: [PATCH] =?UTF-8?q?refactor(tenant):=20=E4=BC=98=E5=8C=96=E5=8F=8A?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=A7=9F=E6=88=B7=E7=9B=B8=E5=85=B3=E9=83=A8?= =?UTF-8?q?=E5=88=86=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移动 TenantExtensionProperties 到 common 模块 - 修复 MenuController#tree 接口 setExcludeMenuIdList 方法判断非默认租户条件缺失 - 修复更新租户套餐菜单,没有及时更新在线用户数据权限(后面考虑重构 satoken 权限数据读取部分) - TenantService 接口 getByDomain => getIdByDomain、getByCode => getIdByCode - 移除 MenuService 中已废弃的方法 - LogDaoLocalImpl 还原(未测出租户用户操作,无租户 ID 问题) - 优化 pg 数据库脚本,移除菜单表的租户相关字段 - 其他代码优化 --- .../config/TenantExtensionProperties.java | 12 ++- .../tenant/config/DefaultTenantProvider.java | 8 +- .../tenant/config/TenantConfiguration.java | 1 + .../tenant/controller/CommonController.java | 13 +-- .../tenant/controller/PackageController.java | 2 +- .../handler/TenantDataHandlerForSystem.java | 30 ++++--- .../admin/tenant/service/TenantService.java | 8 +- .../service/impl/TenantServiceImpl.java | 82 +++++++++++-------- .../admin/config/log/LogConfiguration.java | 8 +- .../admin/config/log/LogDaoLocalImpl.java | 11 +-- .../src/main/resources/config/application.yml | 4 +- .../postgresql/plugin/plugin_tenant.sql | 7 -- .../admin/auth/AbstractLoginHandler.java | 10 ++- .../auth/handler/AccountLoginHandler.java | 7 +- .../admin/auth/handler/EmailLoginHandler.java | 7 +- .../admin/auth/handler/PhoneLoginHandler.java | 7 +- .../auth/handler/SocialLoginHandler.java | 7 +- .../admin/auth/model/resp/LoginResp.java | 5 +- .../system/controller/MenuController.java | 13 ++- .../admin/system/service/MenuService.java | 17 +--- .../admin/system/service/RoleMenuService.java | 4 +- .../admin/system/service/RoleService.java | 7 ++ .../system/service/impl/MenuServiceImpl.java | 77 +++-------------- .../system/service/impl/RoleServiceImpl.java | 50 ++++++----- 24 files changed, 164 insertions(+), 233 deletions(-) rename {continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant => continew-common/src/main/java/top/continew/admin/common}/config/TenantExtensionProperties.java (80%) diff --git a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/config/TenantExtensionProperties.java b/continew-common/src/main/java/top/continew/admin/common/config/TenantExtensionProperties.java similarity index 80% rename from continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/config/TenantExtensionProperties.java rename to continew-common/src/main/java/top/continew/admin/common/config/TenantExtensionProperties.java index bf18e033..e7d3dbab 100644 --- a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/config/TenantExtensionProperties.java +++ b/continew-common/src/main/java/top/continew/admin/common/config/TenantExtensionProperties.java @@ -14,11 +14,12 @@ * limitations under the License. */ -package top.continew.admin.tenant.config; +package top.continew.admin.common.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import top.continew.starter.core.constant.PropertiesConstants; +import top.continew.starter.extension.tenant.context.TenantContextHolder; import java.util.List; @@ -47,4 +48,13 @@ public class TenantExtensionProperties { * 忽略菜单 ID(租户不能使用的菜单) */ private List ignoreMenus; + + /** + * 是否为默认租户 + * + * @return 是否为默认租户 + */ + public boolean isDefaultTenant() { + return defaultTenantId.equals(TenantContextHolder.getTenantId()); + } } diff --git a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/config/DefaultTenantProvider.java b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/config/DefaultTenantProvider.java index 5ab8a716..6fba3911 100644 --- a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/config/DefaultTenantProvider.java +++ b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/config/DefaultTenantProvider.java @@ -19,7 +19,7 @@ package top.continew.admin.tenant.config; import cn.hutool.core.util.StrUtil; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; -import top.continew.admin.tenant.model.entity.TenantDO; +import top.continew.admin.common.config.TenantExtensionProperties; import top.continew.admin.tenant.service.TenantService; import top.continew.starter.core.util.ServletUtils; import top.continew.starter.core.util.validation.CheckUtils; @@ -57,9 +57,9 @@ public class DefaultTenantProvider implements TenantProvider { if (StrUtil.isBlank(tenantCode)) { return context; } - TenantDO tenant = tenantService.getByCode(tenantCode); - CheckUtils.throwIfNull(tenant, "编码为 [%s] 的租户不存在".formatted(tenantCode)); - tenantId = tenant.getId(); + Long id = tenantService.getIdByCode(tenantCode); + CheckUtils.throwIfNull(id, "编码为 [%s] 的租户不存在".formatted(tenantCode)); + tenantId = id; } else { // 指定租户 tenantId = Long.parseLong(tenantIdAsString); diff --git a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/config/TenantConfiguration.java b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/config/TenantConfiguration.java index 75b236f9..e28528ef 100644 --- a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/config/TenantConfiguration.java +++ b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/config/TenantConfiguration.java @@ -19,6 +19,7 @@ package top.continew.admin.tenant.config; import org.springdoc.core.models.GroupedOpenApi; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import top.continew.admin.common.config.TenantExtensionProperties; import top.continew.admin.tenant.service.TenantService; import top.continew.starter.extension.tenant.annotation.ConditionalOnEnabledTenant; import top.continew.starter.extension.tenant.config.TenantProvider; diff --git a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/controller/CommonController.java b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/controller/CommonController.java index a37e553a..99f80f7e 100644 --- a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/controller/CommonController.java +++ b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/controller/CommonController.java @@ -25,7 +25,6 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import top.continew.admin.tenant.model.entity.TenantDO; import top.continew.admin.tenant.model.query.PackageQuery; import top.continew.admin.tenant.service.PackageService; import top.continew.admin.tenant.service.TenantService; @@ -60,15 +59,11 @@ public class CommonController { return packageService.listDict(query, sortQuery); } - @Operation(summary = "根据域名查询租户ID", description = "根据域名查询租户编码") @SaIgnore @TenantIgnore - @GetMapping("/id/domain") - public Long getTenantIdByUrl(@RequestParam("domain") String domain) { - TenantDO tenantDO = tenantService.getByDomain(domain); - if (tenantDO != null) { - return tenantDO.getId(); - } - return null; + @Operation(summary = "根据域名查询租户 ID", description = "根据域名查询租户 ID") + @GetMapping("/id") + public Long getTenantIdByDomain(@RequestParam String domain) { + return tenantService.getIdByDomain(domain); } } diff --git a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/controller/PackageController.java b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/controller/PackageController.java index 6419c6c3..6fa0fe9c 100644 --- a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/controller/PackageController.java +++ b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/controller/PackageController.java @@ -24,7 +24,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import top.continew.admin.common.base.controller.BaseController; -import top.continew.admin.tenant.config.TenantExtensionProperties; +import top.continew.admin.common.config.TenantExtensionProperties; import top.continew.admin.common.enums.DisEnableStatusEnum; import top.continew.admin.system.model.query.MenuQuery; import top.continew.admin.system.service.MenuService; diff --git a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/handler/TenantDataHandlerForSystem.java b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/handler/TenantDataHandlerForSystem.java index 178a0429..6afffcde 100644 --- a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/handler/TenantDataHandlerForSystem.java +++ b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/handler/TenantDataHandlerForSystem.java @@ -69,7 +69,6 @@ public class TenantDataHandlerForSystem implements TenantDataHandler { private final PackageMenuService packageMenuService; private final DeptMapper deptMapper; - private final MenuMapper menuMapper; private final RoleMapper roleMapper; private final RoleMenuService roleMenuService; private final RoleMenuMapper roleMenuMapper; @@ -93,11 +92,10 @@ public class TenantDataHandlerForSystem implements TenantDataHandler { TenantUtils.execute(tenantId, () -> { // 初始化部门 Long deptId = this.initDeptData(tenant); - // 初始化菜单 - List menuIds = packageMenuService.listMenuIdsByPackageId(tenant.getPackageId()); // 初始化角色 Long roleId = this.initRoleData(tenant); // 角色绑定菜单 + List menuIds = packageMenuService.listMenuIdsByPackageId(tenant.getPackageId()); roleMenuService.add(menuIds, roleId); // 初始化管理用户 Long userId = this.initUserData(tenant, deptId); @@ -116,30 +114,30 @@ public class TenantDataHandlerForSystem implements TenantDataHandler { for (UserDO user : userList) { StpUtil.logout(user.getId()); } - Wrapper dw = Wrappers.query().eq("1", 1); + Wrapper queryWrapper = Wrappers.query().eq("1", 1); // 部门清除 - deptMapper.delete(dw); + deptMapper.delete(queryWrapper); // 文件清除 List fileIds = CollUtils.mapToList(fileService.list(), FileDO::getId); if (!fileIds.isEmpty()) { fileService.delete(fileIds); } // 日志清除 - logMapper.delete(dw); + logMapper.delete(queryWrapper); // 消息清除 - messageMapper.delete(dw); - messageUserMapper.delete(dw); + messageMapper.delete(queryWrapper); + messageUserMapper.delete(queryWrapper); // 通知清除 - noticeMapper.delete(dw); + noticeMapper.delete(queryWrapper); // 角色相关数据清除 - roleMapper.delete(dw); - roleDeptMapper.delete(dw); - roleMenuMapper.delete(dw); + roleMapper.delete(queryWrapper); + roleDeptMapper.delete(queryWrapper); + roleMenuMapper.delete(queryWrapper); // 用户数据清除 - userMapper.delete(dw); - userPasswordHistoryMapper.delete(dw); - userRoleMapper.delete(dw); - userSocialMapper.delete(dw); + userMapper.delete(queryWrapper); + userPasswordHistoryMapper.delete(queryWrapper); + userRoleMapper.delete(queryWrapper); + userSocialMapper.delete(queryWrapper); } /** diff --git a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/service/TenantService.java b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/service/TenantService.java index e4e69a6a..50337284 100644 --- a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/service/TenantService.java +++ b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/service/TenantService.java @@ -39,17 +39,17 @@ public interface TenantService extends BaseService ids) { - ids.forEach(id -> RedisUtils.delete(TenantCacheConstants.TENANT_KEY_PREFIX + id)); + RedisUtils.deleteByPattern(TenantCacheConstants.TENANT_KEY_PREFIX + StringConstants.ASTERISK); } @Override - @Cached(name = TenantCacheConstants.TENANT_KEY_PREFIX, key = "#id") - public TenantDO getById(Serializable id) { - return super.getById(id); + @Cached(name = TenantCacheConstants.TENANT_KEY_PREFIX, key = "#domain") + public Long getIdByDomain(String domain) { + return baseMapper.lambdaQuery() + .select(TenantDO::getId) + .eq(TenantDO::getDomain, domain) + .oneOpt() + .map(TenantDO::getId) + .orElse(null); } @Override - public TenantDO getByDomain(String domain) { - return baseMapper.lambdaQuery().eq(TenantDO::getDomain, domain).oneOpt().orElse(null); - } - - @Override - public TenantDO getByCode(String code) { - return baseMapper.lambdaQuery().eq(TenantDO::getCode, code).oneOpt().orElse(null); + @Cached(name = TenantCacheConstants.TENANT_KEY_PREFIX, key = "#code") + public Long getIdByCode(String code) { + return baseMapper.lambdaQuery() + .select(TenantDO::getId) + .eq(TenantDO::getCode, code) + .oneOpt() + .map(TenantDO::getId) + .orElse(null); } @Override @@ -147,31 +153,39 @@ public class TenantServiceImpl extends BaseServiceImpl newMenuIds, Long packageId) { List tenantIdList = this.listIdByPackageId(packageId); if (CollUtil.isEmpty(tenantIdList)) { return; } - //删除旧菜单 - tenantIdList.forEach(tenantId -> TenantUtils.execute(tenantId, () -> roleMenuService.remove(Wrappers - .lambdaQuery(RoleMenuDO.class) - .notIn(RoleMenuDO::getMenuId, newMenuIds)))); - //新增菜单 + // 删除旧菜单 tenantIdList.forEach(tenantId -> TenantUtils.execute(tenantId, () -> { - RoleDO roleDO = roleService.getByCode(SysConstants.TENANT_ADMIN_ROLE_CODE); - List oldMenuIds = roleMenuService.list(Wrappers.lambdaQuery(RoleMenuDO.class) - .eq(RoleMenuDO::getRoleId, roleDO.getId())).stream().map(RoleMenuDO::getMenuId).toList(); - List addMenuIds = CollUtil.disjunction(newMenuIds, oldMenuIds).stream().toList(); - if (CollUtil.isNotEmpty(addMenuIds)) { - List roleMenuDOList = new ArrayList<>(); - for (Long addMenuId : addMenuIds) { - RoleMenuDO roleMenuDO = new RoleMenuDO(roleDO.getId(), addMenuId); - roleMenuDOList.add(roleMenuDO); - } - roleMenuService.saveBatch(roleMenuDOList, roleMenuDOList.size()); + // 更新在线用户上下文 + List roleMenuList = roleMenuService.lambdaQuery() + .select(RoleMenuDO::getRoleId) + .notIn(RoleMenuDO::getMenuId, newMenuIds) + .list(); + Set roleIdSet = CollUtils.mapToSet(roleMenuList, RoleMenuDO::getRoleId); + roleIdSet.forEach(roleService::updateUserContext); + // 删除旧菜单 + roleMenuService.lambdaUpdate().notIn(RoleMenuDO::getMenuId, newMenuIds).remove(); + })); + // 租户管理员:新增菜单 + tenantIdList.forEach(tenantId -> TenantUtils.execute(tenantId, () -> { + RoleDO role = roleService.getByCode(SysConstants.TENANT_ADMIN_ROLE_CODE); + List oldMenuIdList = roleMenuService.listMenuIdByRoleIds(List.of(role.getId())); + Collection addMenuIdList = CollUtil.disjunction(newMenuIds, oldMenuIdList); + if (CollUtil.isNotEmpty(addMenuIdList)) { + List roleMenuList = addMenuIdList.stream() + .map(menuId -> new RoleMenuDO(role.getId(), menuId)) + .toList(); + roleMenuService.saveBatch(roleMenuList, roleMenuList.size()); + // 更新在线用户上下文 + roleService.updateUserContext(role.getId()); } })); - //清理角色菜单缓存 + // 删除缓存 RedisUtils.deleteByPattern(CacheConstants.ROLE_MENU_KEY_PREFIX + StringConstants.ASTERISK); } diff --git a/continew-server/src/main/java/top/continew/admin/config/log/LogConfiguration.java b/continew-server/src/main/java/top/continew/admin/config/log/LogConfiguration.java index 42d88523..1586a9df 100644 --- a/continew-server/src/main/java/top/continew/admin/config/log/LogConfiguration.java +++ b/continew-server/src/main/java/top/continew/admin/config/log/LogConfiguration.java @@ -20,7 +20,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import top.continew.admin.system.mapper.LogMapper; import top.continew.admin.system.service.UserService; -import top.continew.starter.extension.tenant.autoconfigure.TenantProperties; import top.continew.starter.log.annotation.ConditionalOnEnabledLog; import top.continew.starter.log.dao.LogDao; import top.continew.starter.trace.autoconfigure.TraceProperties; @@ -39,10 +38,7 @@ public class LogConfiguration { * 日志持久层接口本地实现类 */ @Bean - public LogDao logDao(UserService userService, - LogMapper logMapper, - TraceProperties traceProperties, - TenantProperties tenantProperties) { - return new LogDaoLocalImpl(userService, logMapper, traceProperties, tenantProperties); + public LogDao logDao(UserService userService, LogMapper logMapper, TraceProperties traceProperties) { + return new LogDaoLocalImpl(userService, logMapper, traceProperties); } } diff --git a/continew-server/src/main/java/top/continew/admin/config/log/LogDaoLocalImpl.java b/continew-server/src/main/java/top/continew/admin/config/log/LogDaoLocalImpl.java index 7cd64e1c..46e05140 100644 --- a/continew-server/src/main/java/top/continew/admin/config/log/LogDaoLocalImpl.java +++ b/continew-server/src/main/java/top/continew/admin/config/log/LogDaoLocalImpl.java @@ -41,7 +41,7 @@ import top.continew.admin.system.service.UserService; import top.continew.starter.core.constant.StringConstants; import top.continew.starter.core.util.ExceptionUtils; import top.continew.starter.core.util.StrUtils; -import top.continew.starter.extension.tenant.autoconfigure.TenantProperties; +import top.continew.starter.extension.tenant.context.TenantContextHolder; import top.continew.starter.extension.tenant.util.TenantUtils; import top.continew.starter.log.dao.LogDao; import top.continew.starter.log.model.LogRecord; @@ -67,7 +67,6 @@ public class LogDaoLocalImpl implements LogDao { private final UserService userService; private final LogMapper logMapper; private final TraceProperties traceProperties; - private final TenantProperties tenantProperties; @Async @Override @@ -88,12 +87,8 @@ public class LogDaoLocalImpl implements LogDao { logDO.setCreateTime(LocalDateTime.ofInstant(logRecord.getTimestamp(), ZoneId.systemDefault())); // 设置操作人 this.setCreateUser(logDO, logRequest, logResponse); - String strTenantId = logRequest.getHeaders().get(tenantProperties.getTenantIdHeader()); - if (StrUtil.isNotBlank(strTenantId)) { - TenantUtils.execute(Long.parseLong(strTenantId), () -> logMapper.insert(logDO)); - } else { - logMapper.insert(logDO); - } + // 保存记录 + TenantUtils.execute(TenantContextHolder.getTenantId(), () -> logMapper.insert(logDO)); } /** diff --git a/continew-server/src/main/resources/config/application.yml b/continew-server/src/main/resources/config/application.yml index c033116a..e1b9a61f 100644 --- a/continew-server/src/main/resources/config/application.yml +++ b/continew-server/src/main/resources/config/application.yml @@ -215,6 +215,7 @@ continew-starter.tenant: - tenant_package_menu # 租户套餐与菜单关联表 - gen_config # 代码生成配置表 - gen_field_config # 代码生成字段配置表 + - sys_menu # 菜单表 - sys_dict # 字典表 - sys_dict_item # 字典项表 - sys_option # 参数表 @@ -223,9 +224,9 @@ continew-starter.tenant: - sys_sms_log # 短信日志表 - sys_client # 客户端表 - sys_app # 应用表 - - sys_menu # 菜单表 # 忽略菜单 ID(租户不能使用的菜单) ignore-menus: + - 1050 # 菜单管理 - 1130 # 字典管理 - 1140 # 字典项管理 - 1150 # 系统配置 @@ -234,7 +235,6 @@ continew-starter.tenant: - 7000 # 能力开放 - 8000 # 任务调度 - 9000 # 开发工具 - - 1050 # 菜单管理 --- ### 限流器配置 continew-starter: diff --git a/continew-server/src/main/resources/db/changelog/postgresql/plugin/plugin_tenant.sql b/continew-server/src/main/resources/db/changelog/postgresql/plugin/plugin_tenant.sql index 93ca2157..8a593328 100644 --- a/continew-server/src/main/resources/db/changelog/postgresql/plugin/plugin_tenant.sql +++ b/continew-server/src/main/resources/db/changelog/postgresql/plugin/plugin_tenant.sql @@ -76,10 +76,6 @@ COMMENT ON COLUMN "tenant_package_menu"."menu_id" IS '菜单ID'; COMMENT ON TABLE "tenant_package_menu" IS '租户套餐和菜单关联表'; -- 为已有表增加租户字段 -ALTER TABLE "sys_menu" ADD COLUMN "tenant_id" int8 NOT NULL DEFAULT 0; -COMMENT ON COLUMN "sys_menu"."tenant_id" IS '租户ID'; -CREATE INDEX "idx_menu_tenant_id" ON "sys_menu" ("tenant_id"); - ALTER TABLE "sys_dept" ADD COLUMN "tenant_id" int8 NOT NULL DEFAULT 0; COMMENT ON COLUMN "sys_dept"."tenant_id" IS '租户ID'; CREATE INDEX "idx_dept_tenant_id" ON "sys_dept" ("tenant_id"); @@ -141,9 +137,6 @@ COMMENT ON COLUMN "sys_app"."tenant_id" IS '租户ID'; CREATE INDEX "idx_app_tenant_id" ON "sys_app" ("tenant_id"); -- 调整唯一索引 -ALTER TABLE "sys_menu" DROP INDEX "uk_menu_title_parent_id"; -CREATE UNIQUE INDEX "uk_menu_title_parent_id" ON "sys_menu" ("title", "parent_id", "tenant_id"); - ALTER TABLE "sys_dept" DROP INDEX "uk_dept_name_parent_id"; CREATE UNIQUE INDEX "uk_dept_name_parent_id" ON "sys_dept" ("name", "parent_id", "tenant_id"); diff --git a/continew-system/src/main/java/top/continew/admin/auth/AbstractLoginHandler.java b/continew-system/src/main/java/top/continew/admin/auth/AbstractLoginHandler.java index 015aff56..47aef8c6 100644 --- a/continew-system/src/main/java/top/continew/admin/auth/AbstractLoginHandler.java +++ b/continew-system/src/main/java/top/continew/admin/auth/AbstractLoginHandler.java @@ -24,6 +24,7 @@ import jakarta.servlet.http.HttpServletRequest; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; import top.continew.admin.auth.model.req.LoginReq; +import top.continew.admin.auth.model.resp.LoginResp; import top.continew.admin.common.context.RoleContext; import top.continew.admin.common.context.UserContext; import top.continew.admin.common.context.UserContextHolder; @@ -88,9 +89,9 @@ public abstract class AbstractLoginHandler implements LoginH * * @param user 用户信息 * @param client 客户端信息 - * @return token 令牌信息 + * @return 登录响应参数 */ - protected String authenticate(UserDO user, ClientResp client) { + protected LoginResp authenticate(UserDO user, ClientResp client) { // 获取权限、角色、密码过期天数 Long userId = user.getId(); Long tenantId = TenantContextHolder.getTenantId(); @@ -127,7 +128,10 @@ public abstract class AbstractLoginHandler implements LoginH StpUtil.login(userContext.getId(), loginParameter.setExtraData(BeanUtil .beanToMap(new UserExtraContext(ServletUtils.getRequest())))); UserContextHolder.setContext(userContext); - return StpUtil.getTokenValue(); + return LoginResp.builder() + .token(StpUtil.getTokenValue()) + .tenantId(TenantContextHolder.isTenantEnabled() ? TenantContextHolder.getTenantId() : null) + .build(); } /** diff --git a/continew-system/src/main/java/top/continew/admin/auth/handler/AccountLoginHandler.java b/continew-system/src/main/java/top/continew/admin/auth/handler/AccountLoginHandler.java index 0277998f..ed186727 100644 --- a/continew-system/src/main/java/top/continew/admin/auth/handler/AccountLoginHandler.java +++ b/continew-system/src/main/java/top/continew/admin/auth/handler/AccountLoginHandler.java @@ -39,7 +39,6 @@ import top.continew.starter.cache.redisson.util.RedisUtils; import top.continew.starter.core.util.ExceptionUtils; import top.continew.starter.core.util.validation.CheckUtils; import top.continew.starter.core.util.validation.ValidationUtils; -import top.continew.starter.extension.tenant.context.TenantContextHolder; import java.time.Duration; @@ -71,11 +70,7 @@ public class AccountLoginHandler extends AbstractLoginHandler { // 检查用户状态 super.checkUserStatus(user); // 执行认证 - String token = this.authenticate(user, client); - return LoginResp.builder() - .token(token) - .tenantId(TenantContextHolder.isTenantEnabled() ? TenantContextHolder.getTenantId() : null) - .build(); + return super.authenticate(user, client); } @Override diff --git a/continew-system/src/main/java/top/continew/admin/auth/handler/EmailLoginHandler.java b/continew-system/src/main/java/top/continew/admin/auth/handler/EmailLoginHandler.java index e7ac5dc8..8c38ec6d 100644 --- a/continew-system/src/main/java/top/continew/admin/auth/handler/EmailLoginHandler.java +++ b/continew-system/src/main/java/top/continew/admin/auth/handler/EmailLoginHandler.java @@ -27,7 +27,6 @@ import top.continew.admin.system.model.entity.user.UserDO; import top.continew.admin.system.model.resp.ClientResp; import top.continew.starter.cache.redisson.util.RedisUtils; import top.continew.starter.core.util.validation.ValidationUtils; -import top.continew.starter.extension.tenant.context.TenantContextHolder; /** * 邮箱登录处理器 @@ -47,11 +46,7 @@ public class EmailLoginHandler extends AbstractLoginHandler { // 检查用户状态 super.checkUserStatus(user); // 执行认证 - String token = super.authenticate(user, client); - return LoginResp.builder() - .token(token) - .tenantId(TenantContextHolder.isTenantEnabled() ? TenantContextHolder.getTenantId() : null) - .build(); + return super.authenticate(user, client); } @Override diff --git a/continew-system/src/main/java/top/continew/admin/auth/handler/PhoneLoginHandler.java b/continew-system/src/main/java/top/continew/admin/auth/handler/PhoneLoginHandler.java index 6d21a217..f9a1c92f 100644 --- a/continew-system/src/main/java/top/continew/admin/auth/handler/PhoneLoginHandler.java +++ b/continew-system/src/main/java/top/continew/admin/auth/handler/PhoneLoginHandler.java @@ -27,7 +27,6 @@ import top.continew.admin.system.model.entity.user.UserDO; import top.continew.admin.system.model.resp.ClientResp; import top.continew.starter.cache.redisson.util.RedisUtils; import top.continew.starter.core.util.validation.ValidationUtils; -import top.continew.starter.extension.tenant.context.TenantContextHolder; /** * 手机号登录处理器 @@ -47,11 +46,7 @@ public class PhoneLoginHandler extends AbstractLoginHandler { // 检查用户状态 super.checkUserStatus(user); // 执行认证 - String token = super.authenticate(user, client); - return LoginResp.builder() - .token(token) - .tenantId(TenantContextHolder.isTenantEnabled() ? TenantContextHolder.getTenantId() : null) - .build(); + return super.authenticate(user, client); } @Override diff --git a/continew-system/src/main/java/top/continew/admin/auth/handler/SocialLoginHandler.java b/continew-system/src/main/java/top/continew/admin/auth/handler/SocialLoginHandler.java index 17cf8429..bc4cc668 100644 --- a/continew-system/src/main/java/top/continew/admin/auth/handler/SocialLoginHandler.java +++ b/continew-system/src/main/java/top/continew/admin/auth/handler/SocialLoginHandler.java @@ -53,7 +53,6 @@ import top.continew.admin.system.service.UserSocialService; import top.continew.starter.core.autoconfigure.application.ApplicationProperties; import top.continew.starter.core.exception.BadRequestException; import top.continew.starter.core.util.validation.ValidationUtils; -import top.continew.starter.extension.tenant.context.TenantContextHolder; import java.time.LocalDateTime; import java.util.Collections; @@ -127,11 +126,7 @@ public class SocialLoginHandler extends AbstractLoginHandler { userSocial.setLastLoginTime(LocalDateTime.now()); userSocialService.saveOrUpdate(userSocial); // 执行认证 - String token = super.authenticate(user, client); - return LoginResp.builder() - .token(token) - .tenantId(TenantContextHolder.isTenantEnabled() ? TenantContextHolder.getTenantId() : null) - .build(); + return super.authenticate(user, client); } @Override diff --git a/continew-system/src/main/java/top/continew/admin/auth/model/resp/LoginResp.java b/continew-system/src/main/java/top/continew/admin/auth/model/resp/LoginResp.java index d6d7d45a..0f329a5a 100644 --- a/continew-system/src/main/java/top/continew/admin/auth/model/resp/LoginResp.java +++ b/continew-system/src/main/java/top/continew/admin/auth/model/resp/LoginResp.java @@ -43,6 +43,9 @@ public class LoginResp implements Serializable { @Schema(description = "令牌", example = "eyJ0eXAiOiJlV1QiLCJhbGciqiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb29pbiIsImxvZ2luSWQiOjEsInJuU3RyIjoiSjd4SUljYnU5cmNwU09vQ3Uyc1ND1BYYTYycFRjcjAifQ.KUPOYm-2wfuLUSfEEAbpGE527fzmkAJG7sMNcQ0pUZ8") private String token; - @Schema(description = "租户ID", example = "0") + /** + * 租户 ID + */ + @Schema(description = "租户 ID", example = "0") private Long tenantId; } diff --git a/continew-system/src/main/java/top/continew/admin/system/controller/MenuController.java b/continew-system/src/main/java/top/continew/admin/system/controller/MenuController.java index bd419e0a..64bedb6c 100644 --- a/continew-system/src/main/java/top/continew/admin/system/controller/MenuController.java +++ b/continew-system/src/main/java/top/continew/admin/system/controller/MenuController.java @@ -23,11 +23,12 @@ import cn.hutool.core.util.StrUtil; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; -import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.RestController; -import top.continew.admin.common.constant.CacheConstants; import top.continew.admin.common.base.controller.BaseController; +import top.continew.admin.common.config.TenantExtensionProperties; +import top.continew.admin.common.constant.CacheConstants; import top.continew.admin.system.model.query.MenuQuery; import top.continew.admin.system.model.req.MenuReq; import top.continew.admin.system.model.resp.MenuResp; @@ -40,6 +41,7 @@ import top.continew.starter.extension.crud.annotation.CrudApi; import top.continew.starter.extension.crud.annotation.CrudRequestMapping; import top.continew.starter.extension.crud.enums.Api; import top.continew.starter.extension.crud.model.query.SortQuery; +import top.continew.starter.extension.tenant.context.TenantContextHolder; import java.lang.reflect.Method; import java.util.List; @@ -52,11 +54,12 @@ import java.util.List; */ @Tag(name = "菜单管理 API") @RestController -@AllArgsConstructor +@RequiredArgsConstructor @CrudRequestMapping(value = "/system/menu", api = {Api.TREE, Api.GET, Api.CREATE, Api.UPDATE, Api.BATCH_DELETE}) public class MenuController extends BaseController { private final MenuService menuService; + private final TenantExtensionProperties tenantExtensionProperties; @Operation(summary = "清除缓存", description = "清除缓存") @SaCheckPermission("system:menu:clearCache") @@ -88,7 +91,9 @@ public class MenuController extends BaseController> tree(@Valid MenuQuery query, @Valid SortQuery sortQuery) { - query.setExcludeMenuIdList(menuService.listExcludeTenantMenu()); + if (TenantContextHolder.isTenantEnabled() && !tenantExtensionProperties.isDefaultTenant()) { + query.setExcludeMenuIdList(menuService.listExcludeTenantMenu()); + } return super.tree(query, sortQuery); } diff --git a/continew-system/src/main/java/top/continew/admin/system/service/MenuService.java b/continew-system/src/main/java/top/continew/admin/system/service/MenuService.java index 86a65092..d756e423 100644 --- a/continew-system/src/main/java/top/continew/admin/system/service/MenuService.java +++ b/continew-system/src/main/java/top/continew/admin/system/service/MenuService.java @@ -51,22 +51,9 @@ public interface MenuService extends BaseService listByRoleId(Long roleId); /** - * 删除租户菜单 + * 查询租户排除的菜单 ID 列表 * - * @param menuS 菜单列表 - */ - void deleteTenantMenus(List menuS); - - /** - * 新增租户菜单 - * - * @param menu 新增的菜单 - * @param parentMenu 父菜单 - */ - void addTenantMenu(MenuDO menu, MenuDO parentMenu); - - /** - * 查询租户排除的菜单 + * @return 租户排除的菜单 ID 列表 */ List listExcludeTenantMenu(); } diff --git a/continew-system/src/main/java/top/continew/admin/system/service/RoleMenuService.java b/continew-system/src/main/java/top/continew/admin/system/service/RoleMenuService.java index 5d068da9..a50bacd6 100644 --- a/continew-system/src/main/java/top/continew/admin/system/service/RoleMenuService.java +++ b/continew-system/src/main/java/top/continew/admin/system/service/RoleMenuService.java @@ -39,14 +39,14 @@ public interface RoleMenuService extends IService { boolean add(List menuIds, Long roleId); /** - * 根据角色 ID 删除 + * 根据角色 ID 列表删除 * * @param roleIds 角色 ID 列表 */ void deleteByRoleIds(List roleIds); /** - * 根据角色 ID 查询 + * 根据角色 ID 列表查询 * * @param roleIds 角色 ID 列表 * @return 菜单 ID 列表 diff --git a/continew-system/src/main/java/top/continew/admin/system/service/RoleService.java b/continew-system/src/main/java/top/continew/admin/system/service/RoleService.java index 5b9c2212..7e5b6036 100644 --- a/continew-system/src/main/java/top/continew/admin/system/service/RoleService.java +++ b/continew-system/src/main/java/top/continew/admin/system/service/RoleService.java @@ -53,6 +53,13 @@ public interface RoleService extends BaseService userIds); + /** + * 更新用户上下文 + * + * @param roleId 角色 ID + */ + void updateUserContext(Long roleId); + /** * 根据用户 ID 查询权限码 * diff --git a/continew-system/src/main/java/top/continew/admin/system/service/impl/MenuServiceImpl.java b/continew-system/src/main/java/top/continew/admin/system/service/impl/MenuServiceImpl.java index 33120889..9212d06e 100644 --- a/continew-system/src/main/java/top/continew/admin/system/service/impl/MenuServiceImpl.java +++ b/continew-system/src/main/java/top/continew/admin/system/service/impl/MenuServiceImpl.java @@ -18,11 +18,11 @@ package top.continew.admin.system.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.collection.ListUtil; import cn.hutool.core.util.StrUtil; import com.alicp.jetcache.anno.Cached; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import jakarta.annotation.Resource; import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import top.continew.admin.common.base.service.BaseServiceImpl; @@ -31,20 +31,18 @@ import top.continew.admin.common.constant.SysConstants; import top.continew.admin.common.enums.DisEnableStatusEnum; import top.continew.admin.system.enums.MenuTypeEnum; import top.continew.admin.system.mapper.MenuMapper; -import top.continew.admin.system.mapper.RoleMapper; import top.continew.admin.system.model.entity.MenuDO; import top.continew.admin.system.model.entity.RoleDO; -import top.continew.admin.system.model.entity.RoleMenuDO; import top.continew.admin.system.model.query.MenuQuery; import top.continew.admin.system.model.req.MenuReq; import top.continew.admin.system.model.resp.MenuResp; import top.continew.admin.system.service.MenuService; -import top.continew.admin.system.service.RoleMenuService; +import top.continew.admin.system.service.RoleService; import top.continew.starter.cache.redisson.util.RedisUtils; import top.continew.starter.core.constant.StringConstants; +import top.continew.starter.core.util.CollUtils; import top.continew.starter.core.util.validation.CheckUtils; -import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -58,8 +56,9 @@ import java.util.Set; @RequiredArgsConstructor public class MenuServiceImpl extends BaseServiceImpl implements MenuService { - private final RoleMenuService roleMenuService; - private final RoleMapper roleMapper; + @Lazy + @Resource + private RoleService roleService; @Override public Long create(MenuReq req) { @@ -114,66 +113,12 @@ public class MenuServiceImpl extends BaseServiceImpl menuList) { - if (CollUtil.isEmpty(menuList)) { - return; - } - List delIds = new ArrayList<>(); - for (MenuDO menu : menuList) { - MenuDO parentMenu = baseMapper.query() - .eq(menu.getType().equals(MenuTypeEnum.BUTTON), "CONCAT(title,permission)", menu.getTitle() + menu - .getPermission()) - .eq(!menu.getType().equals(MenuTypeEnum.BUTTON), "name", menu.getName()) - .one(); - if (parentMenu != null) { - delIds.add(parentMenu.getId()); - } - } - if (!delIds.isEmpty()) { - // 菜单删除 - this.delete(delIds); - // 删除绑定关系 - roleMenuService.remove(Wrappers.lambdaQuery(RoleMenuDO.class).in(RoleMenuDO::getMenuId, delIds)); - } - // 删除缓存 - RedisUtils.deleteByPattern(CacheConstants.ROLE_MENU_KEY_PREFIX + StringConstants.ASTERISK); - } - - @Override - public void addTenantMenu(MenuDO menu, MenuDO parentMenu) { - Long parentId = SysConstants.SUPER_PARENT_ID; - if (parentMenu != null) { - MenuDO parent = baseMapper.query() - .eq(parentMenu.getType().equals(MenuTypeEnum.BUTTON), "CONCAT(title,permission)", parentMenu - .getTitle() + parentMenu.getPermission()) - .eq(!parentMenu.getType().equals(MenuTypeEnum.BUTTON), "name", parentMenu.getName()) - .one(); - parentId = parent.getId(); - } - menu.setId(null); - menu.setParentId(parentId); - // 菜单新增 - baseMapper.insert(menu); - // 管理员绑定菜单 - RoleDO role = roleMapper.selectOne(Wrappers.lambdaQuery(RoleDO.class) - .eq(RoleDO::getCode, SysConstants.TENANT_ADMIN_ROLE_CODE)); - roleMenuService.save(new RoleMenuDO(role.getId(), menu.getId())); - // 删除缓存 - RedisUtils.deleteByPattern(CacheConstants.ROLE_MENU_KEY_PREFIX + StringConstants.ASTERISK); - } - @Override public List listExcludeTenantMenu() { - RoleDO role = roleMapper.selectOne(Wrappers.lambdaQuery(RoleDO.class) - .eq(RoleDO::getCode, SysConstants.TENANT_ADMIN_ROLE_CODE)); - if (role == null) { - return ListUtil.of(); - } - List allMenuList = list().stream().map(MenuDO::getId).toList(); - List menuList = baseMapper.selectListByRoleId(role.getId()).stream().map(MenuDO::getId).toList(); - return CollUtil.disjunction(allMenuList, menuList).stream().toList(); + RoleDO role = roleService.getByCode(SysConstants.TENANT_ADMIN_ROLE_CODE); + List allMenuIdList = CollUtils.mapToList(super.list(), MenuDO::getId); + List menuIdList = CollUtils.mapToList(baseMapper.selectListByRoleId(role.getId()), MenuDO::getId); + return CollUtil.disjunction(allMenuIdList, menuIdList).stream().toList(); } /** diff --git a/continew-system/src/main/java/top/continew/admin/system/service/impl/RoleServiceImpl.java b/continew-system/src/main/java/top/continew/admin/system/service/impl/RoleServiceImpl.java index ee5e6e4e..ab3143c4 100644 --- a/continew-system/src/main/java/top/continew/admin/system/service/impl/RoleServiceImpl.java +++ b/continew-system/src/main/java/top/continew/admin/system/service/impl/RoleServiceImpl.java @@ -20,6 +20,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import com.alicp.jetcache.anno.CacheInvalidate; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import jakarta.annotation.Resource; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -57,7 +58,8 @@ import java.util.Set; @RequiredArgsConstructor public class RoleServiceImpl extends BaseServiceImpl implements RoleService { - private final MenuService menuService; + @Resource + private MenuService menuService; private final RoleMenuService roleMenuService; private final RoleDeptService roleDeptService; private final UserRoleService userRoleService; @@ -116,6 +118,17 @@ public class RoleServiceImpl extends BaseServiceImpl list = menuService.listByRoleId(roleId); + List menuIds = CollUtils.mapToList(list, MenuResp::getId); + detail.setMenuIds(menuIds); + } + } + @Override @Transactional(rollbackFor = Exception.class) @CacheInvalidate(key = "#id", name = CacheConstants.ROLE_MENU_KEY_PREFIX) @@ -143,14 +156,16 @@ public class RoleServiceImpl extends BaseServiceImpl list = menuService.listByRoleId(roleId); - List menuIds = CollUtils.mapToList(list, MenuResp::getId); - detail.setMenuIds(menuIds); - } + public void updateUserContext(Long roleId) { + List userIdList = userRoleService.listUserIdByRoleId(roleId); + userIdList.forEach(userId -> { + UserContext userContext = UserContextHolder.getContext(userId); + if (userContext != null) { + userContext.setRoles(this.listByUserId(userId)); + userContext.setPermissions(this.listPermissionByUserId(userId)); + UserContextHolder.setContext(userContext); + } + }); } @Override @@ -232,21 +247,4 @@ public class RoleServiceImpl extends BaseServiceImpl userIdList = userRoleService.listUserIdByRoleId(roleId); - userIdList.parallelStream().forEach(userId -> { - UserContext userContext = UserContextHolder.getContext(userId); - if (userContext != null) { - userContext.setRoles(this.listByUserId(userId)); - userContext.setPermissions(this.listPermissionByUserId(userId)); - UserContextHolder.setContext(userContext); - } - }); - } }