From c0ff69011fc71eb1bac078faeada3e4b56be5b37 Mon Sep 17 00:00:00 2001 From: ruying408 <1877972603@qq.com> Date: Sun, 13 Apr 2025 00:08:58 +0800 Subject: [PATCH] =?UTF-8?q?upgrade=EF=BC=9A=E5=A4=9A=E7=A7=9F=E6=88=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/cool/core/base/TenantEntity.java | 16 ++++++++++ .../core/config/MyBatisFlexConfiguration.java | 12 ++++++++ .../core/request/RequestParamsFilter.java | 29 +++++++++++-------- .../cool/core/tenant/CoolTenantFactory.java | 14 +++++++++ .../com/cool/core/util/CoolSecurityUtil.java | 8 +++++ .../java/com/cool/core/util/I18nUtil.java | 21 ++++---------- .../java/com/cool/core/util/TenantUtil.java | 14 +++++++++ .../base/entity/sys/BaseSysUserEntity.java | 4 +-- .../sys/impl/BaseSysLoginServiceImpl.java | 1 + src/main/resources/application.yml | 3 ++ .../sys/table/BaseSysUserEntityTableDef.java | 4 ++- 11 files changed, 95 insertions(+), 31 deletions(-) create mode 100644 src/main/java/com/cool/core/base/TenantEntity.java create mode 100644 src/main/java/com/cool/core/tenant/CoolTenantFactory.java create mode 100644 src/main/java/com/cool/core/util/TenantUtil.java diff --git a/src/main/java/com/cool/core/base/TenantEntity.java b/src/main/java/com/cool/core/base/TenantEntity.java new file mode 100644 index 0000000..4e258d5 --- /dev/null +++ b/src/main/java/com/cool/core/base/TenantEntity.java @@ -0,0 +1,16 @@ +package com.cool.core.base; + +import com.mybatisflex.core.activerecord.Model; +import com.tangzc.mybatisflex.autotable.annotation.ColumnDefine; +import lombok.Getter; +import lombok.Setter; +import org.dromara.autotable.annotation.Index; + +/** 租户ID实体类 */ +@Getter +@Setter +public class TenantEntity> extends BaseEntity { + @Index + @ColumnDefine(comment = "租户id") + protected Long tenantId; +} \ No newline at end of file diff --git a/src/main/java/com/cool/core/config/MyBatisFlexConfiguration.java b/src/main/java/com/cool/core/config/MyBatisFlexConfiguration.java index 762c4d2..e7dcfa1 100644 --- a/src/main/java/com/cool/core/config/MyBatisFlexConfiguration.java +++ b/src/main/java/com/cool/core/config/MyBatisFlexConfiguration.java @@ -1,7 +1,11 @@ package com.cool.core.config; +import com.cool.core.tenant.CoolTenantFactory; import com.mybatisflex.core.FlexGlobalConfig; +import com.mybatisflex.core.tenant.TenantFactory; import com.mybatisflex.spring.boot.MyBatisFlexCustomizer; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration @@ -10,6 +14,14 @@ public class MyBatisFlexConfiguration implements MyBatisFlexCustomizer { @Override public void customize(FlexGlobalConfig globalConfig) { // 我们可以在这里进行一些列的初始化配置 + + // 指定多租户列的列名 + FlexGlobalConfig.getDefaultConfig().setTenantColumn("tenant_id"); } + @Bean + @ConditionalOnProperty(name = "cool.multi-tenant.enable", havingValue = "true") + public TenantFactory tenantFactory(){ + return new CoolTenantFactory(); + } } \ No newline at end of file diff --git a/src/main/java/com/cool/core/request/RequestParamsFilter.java b/src/main/java/com/cool/core/request/RequestParamsFilter.java index 2ac9923..cbcc551 100644 --- a/src/main/java/com/cool/core/request/RequestParamsFilter.java +++ b/src/main/java/com/cool/core/request/RequestParamsFilter.java @@ -36,9 +36,12 @@ public class RequestParamsFilter implements Filter { HttpServletRequest request = (HttpServletRequest) servletRequest; JSONObject requestParams = new JSONObject(); String language = request.getHeader("language"); + String coolEid = request.getHeader("cool-admin-eid"); + Long tenantId = StrUtil.isEmpty(coolEid) ? null : Long.parseLong(coolEid); if (StrUtil.isNotEmpty(request.getContentType()) && request.getContentType().contains("multipart/form-data")) { servletRequest.setAttribute("requestParams", requestParams); servletRequest.setAttribute("cool-language", language); + servletRequest.setAttribute("tenantId", tenantId); filterChain.doFilter(servletRequest, servletResponse); } else { BodyReaderHttpServletRequestWrapper requestWrapper = new BodyReaderHttpServletRequestWrapper(request); @@ -47,38 +50,40 @@ public class RequestParamsFilter implements Filter { body)) { requestParams = JSONUtil.parseObj(body); } - - // 登录状态,设置用户id - setUserId(requestParams); - - requestParams.set("body", body); - requestParams.putAll(getAllRequestParam(request)); - Object jwtObj = request.getAttribute("tokenInfo"); if (jwtObj != null) { requestParams.set("tokenInfo", ((JWT) jwtObj).getPayload().getClaimsJson()); } - requestWrapper.setAttribute("requestParams", requestParams); + // 登录状态,设置用户id + Long currTenantId = setUserId(requestParams); + if (ObjUtil.isNotNull(currTenantId)) { + tenantId = currTenantId; + } requestWrapper.setAttribute("cool-language", language); + request.setAttribute("tenantId", tenantId); + requestParams.set("body", body); + requestParams.putAll(getAllRequestParam(request)); + + requestWrapper.setAttribute("requestParams", requestParams); filterChain.doFilter(requestWrapper, servletResponse); } } - private void setUserId(JSONObject requestParams) { + private Long setUserId(JSONObject requestParams) { UserTypeEnum userTypeEnum = CoolSecurityUtil.getCurrentUserType(); switch (userTypeEnum) { // 只有登录了,才有用户类型, 不然为 UNKNOWN 状态 case ADMIN -> { // 管理后台由于之前已经有逻辑再了,怕会影响到,如果自己有传了值不覆盖 Object o = requestParams.get("userId"); - if (ObjUtil.isNotEmpty(o)) { - return; + if (ObjUtil.isNull(o)) { + requestParams.set("userId", CoolSecurityUtil.getCurrentUserId()); } - requestParams.set("userId", CoolSecurityUtil.getCurrentUserId()); } // app端,userId 为当前登录的用户id case APP -> requestParams.set("userId", CoolSecurityUtil.getCurrentUserId()); } + return CoolSecurityUtil.getTenantId(requestParams); } /** diff --git a/src/main/java/com/cool/core/tenant/CoolTenantFactory.java b/src/main/java/com/cool/core/tenant/CoolTenantFactory.java new file mode 100644 index 0000000..f79ebef --- /dev/null +++ b/src/main/java/com/cool/core/tenant/CoolTenantFactory.java @@ -0,0 +1,14 @@ +package com.cool.core.tenant; + +import com.cool.core.util.TenantUtil; +import com.mybatisflex.core.tenant.TenantFactory; + +public class CoolTenantFactory implements TenantFactory { + public Object[] getTenantIds(){ + Long tenantId = TenantUtil.getTenantId(); + if (tenantId == null) { + return null; + } + return new Object[]{tenantId}; + } +} diff --git a/src/main/java/com/cool/core/util/CoolSecurityUtil.java b/src/main/java/com/cool/core/util/CoolSecurityUtil.java index 90ee147..5173cca 100644 --- a/src/main/java/com/cool/core/util/CoolSecurityUtil.java +++ b/src/main/java/com/cool/core/util/CoolSecurityUtil.java @@ -42,6 +42,14 @@ public class CoolSecurityUtil { return tokenInfo; } + public static Long getTenantId(JSONObject requestParams) { + JSONObject tokenInfo = requestParams.getJSONObject("tokenInfo"); + if (tokenInfo != null) { + return tokenInfo.getLong("tenantId"); + } + return null; + } + /** * 后台账号退出登录 * diff --git a/src/main/java/com/cool/core/util/I18nUtil.java b/src/main/java/com/cool/core/util/I18nUtil.java index 91b92fb..13d28d5 100644 --- a/src/main/java/com/cool/core/util/I18nUtil.java +++ b/src/main/java/com/cool/core/util/I18nUtil.java @@ -3,7 +3,6 @@ package com.cool.core.util; import cn.hutool.core.io.FileUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; -import jakarta.annotation.PostConstruct; import java.io.File; import java.util.List; import java.util.Map; @@ -36,22 +35,10 @@ public class I18nUtil { private static final Map data = new ConcurrentHashMap<>(); - @PostConstruct - public void init() { - if (!enable) { - return; - } + private void load(String key, File file) { try { - // 获取该目录下所有的 .json 文件 - List jsonFiles = FileUtil.loopFiles(getPath(), file -> - file.isFile() && file.getName().endsWith(".json") - ); - jsonFiles.forEach(file -> { - String parentName = file.getParentFile().getName(); - String content = FileUtil.readUtf8String(file); - String key = parentName + "_" + file.getName().replace(".json", ""); - data.put(key, JSONUtil.parseObj(content)); - }); + String content = FileUtil.readUtf8String(file); + data.put(key, JSONUtil.parseObj(content)); } catch (Exception e) { log.error("读取国际化文件失败", e); } @@ -68,6 +55,8 @@ public class I18nUtil { String key = parentName + "_" + file.getName().replace(".json", ""); if (key.equals(name)) { flag.set(true); + // 加载 + load(key, file); } }); return flag.get(); diff --git a/src/main/java/com/cool/core/util/TenantUtil.java b/src/main/java/com/cool/core/util/TenantUtil.java new file mode 100644 index 0000000..66d20e4 --- /dev/null +++ b/src/main/java/com/cool/core/util/TenantUtil.java @@ -0,0 +1,14 @@ +package com.cool.core.util; + +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; + +public class TenantUtil { + public static Long getTenantId() { + RequestAttributes attributes = RequestContextHolder.getRequestAttributes(); + if (attributes == null) { + return null; + } + return (Long) attributes.getAttribute("tenantId", RequestAttributes.SCOPE_REQUEST); + } +} diff --git a/src/main/java/com/cool/modules/base/entity/sys/BaseSysUserEntity.java b/src/main/java/com/cool/modules/base/entity/sys/BaseSysUserEntity.java index 9a3d5e0..b6a87fc 100644 --- a/src/main/java/com/cool/modules/base/entity/sys/BaseSysUserEntity.java +++ b/src/main/java/com/cool/modules/base/entity/sys/BaseSysUserEntity.java @@ -1,6 +1,6 @@ package com.cool.modules.base.entity.sys; -import com.cool.core.base.BaseEntity; +import com.cool.core.base.TenantEntity; import com.mybatisflex.annotation.Column; import com.mybatisflex.annotation.Table; import com.tangzc.mybatisflex.autotable.annotation.ColumnDefine; @@ -12,7 +12,7 @@ import org.dromara.autotable.annotation.enums.IndexTypeEnum; @Getter @Setter @Table(value = "base_sys_user", comment = "系统用户表") -public class BaseSysUserEntity extends BaseEntity { +public class BaseSysUserEntity extends TenantEntity { @Index @ColumnDefine(comment = "部门ID", type = "bigint") private Long departmentId; diff --git a/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysLoginServiceImpl.java b/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysLoginServiceImpl.java index 1d7cac2..635f268 100644 --- a/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysLoginServiceImpl.java +++ b/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysLoginServiceImpl.java @@ -122,6 +122,7 @@ public class BaseSysLoginServiceImpl implements BaseSysLoginService { .set("roleIds", roleIds) .set("username", baseSysUserEntity.getUsername()) .set("userId", baseSysUserEntity.getId()) + .set("tenantId", baseSysUserEntity.getTenantId()) .set("passwordVersion", baseSysUserEntity.getPasswordV()); String token = jwtTokenUtil.generateToken(tokenInfo); if (StrUtil.isEmpty(refreshToken)) { diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index e2650b4..d7824d7 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -148,6 +148,9 @@ cool: max-pool-size-multiplier: 3 # 队列容量的倍数 queue-capacity-multiplier: 3 + multi-tenant: + # 是否开启多租户,默认关闭 + enable: false # AutoTable配置,根据实体类自动生成表 auto-table: show-banner: false diff --git a/target/generated-sources/annotations/com/cool/modules/base/entity/sys/table/BaseSysUserEntityTableDef.java b/target/generated-sources/annotations/com/cool/modules/base/entity/sys/table/BaseSysUserEntityTableDef.java index 0fbd4e7..44678e9 100644 --- a/target/generated-sources/annotations/com/cool/modules/base/entity/sys/table/BaseSysUserEntityTableDef.java +++ b/target/generated-sources/annotations/com/cool/modules/base/entity/sys/table/BaseSysUserEntityTableDef.java @@ -28,6 +28,8 @@ public class BaseSysUserEntityTableDef extends TableDef { public final QueryColumn SOCKET_ID = new QueryColumn(this, "socket_id"); + public final QueryColumn TENANT_ID = new QueryColumn(this, "tenant_id"); + public final QueryColumn USERNAME = new QueryColumn(this, "username"); public final QueryColumn PASSWORD_V = new QueryColumn(this, "password_v"); @@ -46,7 +48,7 @@ public class BaseSysUserEntityTableDef extends TableDef { /** * 默认字段,不包含逻辑删除或者 large 等字段。 */ - public final QueryColumn[] DEFAULT_COLUMNS = new QueryColumn[]{ID, NAME, EMAIL, PHONE, REMARK, STATUS, HEAD_IMG, NICK_NAME, PASSWORD, SOCKET_ID, USERNAME, PASSWORD_V, CREATE_TIME, UPDATE_TIME, DEPARTMENT_ID}; + public final QueryColumn[] DEFAULT_COLUMNS = new QueryColumn[]{ID, NAME, EMAIL, PHONE, REMARK, STATUS, HEAD_IMG, NICK_NAME, PASSWORD, SOCKET_ID, TENANT_ID, USERNAME, PASSWORD_V, CREATE_TIME, UPDATE_TIME, DEPARTMENT_ID}; public BaseSysUserEntityTableDef() { super("", "base_sys_user");