upgrade:多租户
This commit is contained in:
16
src/main/java/com/cool/core/base/TenantEntity.java
Normal file
16
src/main/java/com/cool/core/base/TenantEntity.java
Normal file
@@ -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<T extends Model<T>> extends BaseEntity<T> {
|
||||
@Index
|
||||
@ColumnDefine(comment = "租户id")
|
||||
protected Long tenantId;
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
14
src/main/java/com/cool/core/tenant/CoolTenantFactory.java
Normal file
14
src/main/java/com/cool/core/tenant/CoolTenantFactory.java
Normal file
@@ -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};
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台账号退出登录
|
||||
*
|
||||
|
||||
@@ -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<String, JSONObject> data = new ConcurrentHashMap<>();
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
if (!enable) {
|
||||
return;
|
||||
}
|
||||
private void load(String key, File file) {
|
||||
try {
|
||||
// 获取该目录下所有的 .json 文件
|
||||
List<File> 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();
|
||||
|
||||
14
src/main/java/com/cool/core/util/TenantUtil.java
Normal file
14
src/main/java/com/cool/core/util/TenantUtil.java
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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<BaseSysUserEntity> {
|
||||
public class BaseSysUserEntity extends TenantEntity<BaseSysUserEntity> {
|
||||
@Index
|
||||
@ColumnDefine(comment = "部门ID", type = "bigint")
|
||||
private Long departmentId;
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -148,6 +148,9 @@ cool:
|
||||
max-pool-size-multiplier: 3
|
||||
# 队列容量的倍数
|
||||
queue-capacity-multiplier: 3
|
||||
multi-tenant:
|
||||
# 是否开启多租户,默认关闭
|
||||
enable: false
|
||||
# AutoTable配置,根据实体类自动生成表
|
||||
auto-table:
|
||||
show-banner: false
|
||||
|
||||
Reference in New Issue
Block a user