Merge remote-tracking branch 'ztcloud/main' into main-ztcloud
# Conflicts: # zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/dept/DeptService.java
This commit is contained in:
5
pom.xml
5
pom.xml
@@ -32,7 +32,7 @@
|
|||||||
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<revision>3.0.45</revision>
|
<revision>3.0.46</revision>
|
||||||
<!-- Maven 相关 -->
|
<!-- Maven 相关 -->
|
||||||
<java.version>17</java.version>
|
<java.version>17</java.version>
|
||||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||||
@@ -271,7 +271,8 @@
|
|||||||
<profile>
|
<profile>
|
||||||
<id>chenbowen</id>
|
<id>chenbowen</id>
|
||||||
<properties>
|
<properties>
|
||||||
<env.name>local</env.name>
|
<!-- <env.name>local</env.name>-->
|
||||||
|
<env.name>dev</env.name>
|
||||||
<!-- <config.server-addr>localhost:8848</config.server-addr>-->
|
<!-- <config.server-addr>localhost:8848</config.server-addr>-->
|
||||||
<config.server-addr>172.16.46.63:30848</config.server-addr>
|
<config.server-addr>172.16.46.63:30848</config.server-addr>
|
||||||
<config.namespace>chenbowen</config.namespace>
|
<config.namespace>chenbowen</config.namespace>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -19,7 +19,8 @@ CREATE TABLE databus_api_definition_credential (
|
|||||||
deleted BIT DEFAULT '0' NOT NULL
|
deleted BIT DEFAULT '0' NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE UNIQUE INDEX uk_databus_api_definition_credential ON databus_api_definition_credential (api_id, credential_id, deleted);
|
-- 去掉错误的唯一索引逻辑
|
||||||
|
-- CREATE UNIQUE INDEX uk_databus_api_definition_credential ON databus_api_definition_credential (api_id, credential_id, deleted);
|
||||||
CREATE INDEX idx_databus_api_definition_credential_api ON databus_api_definition_credential (api_id);
|
CREATE INDEX idx_databus_api_definition_credential_api ON databus_api_definition_credential (api_id);
|
||||||
CREATE INDEX idx_databus_api_definition_credential_cred ON databus_api_definition_credential (credential_id);
|
CREATE INDEX idx_databus_api_definition_credential_cred ON databus_api_definition_credential (credential_id);
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<revision>3.0.45</revision>
|
<revision>3.0.46</revision>
|
||||||
<flatten-maven-plugin.version>1.6.0</flatten-maven-plugin.version>
|
<flatten-maven-plugin.version>1.6.0</flatten-maven-plugin.version>
|
||||||
<!-- 统一依赖管理 -->
|
<!-- 统一依赖管理 -->
|
||||||
<spring.boot.version>3.4.5</spring.boot.version>
|
<spring.boot.version>3.4.5</spring.boot.version>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.zt.plat.framework.common.util.security;
|
package com.zt.plat.framework.common.util.security;
|
||||||
|
|
||||||
import cn.hutool.crypto.SecureUtil;
|
import cn.hutool.crypto.SecureUtil;
|
||||||
|
import com.zt.plat.framework.common.util.json.JsonUtils;
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
import javax.crypto.KeyGenerator;
|
import javax.crypto.KeyGenerator;
|
||||||
@@ -126,7 +127,11 @@ public final class CryptoSignatureUtils {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
sb.append(key).append('=');
|
sb.append(key).append('=');
|
||||||
|
if (value instanceof String || value instanceof Number || value instanceof Boolean) {
|
||||||
sb.append(value);
|
sb.append(value);
|
||||||
|
} else {
|
||||||
|
sb.append(JsonUtils.toJsonString(value));
|
||||||
|
}
|
||||||
sb.append('&');
|
sb.append('&');
|
||||||
}
|
}
|
||||||
if (sb.length() > 0) {
|
if (sb.length() > 0) {
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
|
|||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -18,14 +20,12 @@ import java.util.Set;
|
|||||||
public class BusinessDataPermissionConfiguration {
|
public class BusinessDataPermissionConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public BusinessDataPermissionEntityScanner businessDataPermissionEntityScanner(BeanFactory beanFactory, ApplicationContext applicationContext) {
|
public BusinessDataPermissionEntityScanner businessDataPermissionEntityScanner(BeanFactory beanFactory, ApplicationContext applicationContext, Environment environment) {
|
||||||
Set<String> basePackages = new LinkedHashSet<>();
|
Set<String> basePackages = new LinkedHashSet<>();
|
||||||
|
addConfiguredBasePackages(environment, basePackages);
|
||||||
if (AutoConfigurationPackages.has(beanFactory)) {
|
if (AutoConfigurationPackages.has(beanFactory)) {
|
||||||
basePackages.addAll(AutoConfigurationPackages.get(beanFactory));
|
basePackages.addAll(AutoConfigurationPackages.get(beanFactory));
|
||||||
}
|
}
|
||||||
if (basePackages.isEmpty()) {
|
|
||||||
basePackages.add("com.zt");
|
|
||||||
}
|
|
||||||
ClassLoader classLoader = applicationContext != null
|
ClassLoader classLoader = applicationContext != null
|
||||||
? applicationContext.getClassLoader()
|
? applicationContext.getClassLoader()
|
||||||
: Thread.currentThread().getContextClassLoader();
|
: Thread.currentThread().getContextClassLoader();
|
||||||
@@ -35,6 +35,21 @@ public class BusinessDataPermissionConfiguration {
|
|||||||
return new BusinessDataPermissionEntityScanner(basePackages, classLoader);
|
return new BusinessDataPermissionEntityScanner(basePackages, classLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addConfiguredBasePackages(Environment environment, Set<String> basePackages) {
|
||||||
|
if (environment == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String configured = environment.getProperty("zt.info.base-package");
|
||||||
|
if (!StringUtils.hasText(configured)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (String pkg : configured.split("[,;\\s]+")) {
|
||||||
|
if (StringUtils.hasText(pkg)) {
|
||||||
|
basePackages.add(pkg.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public CompanyDataPermissionRuleCustomizer autoCompanyDataPermissionRuleCustomizer(BusinessDataPermissionEntityScanner scanner) {
|
public CompanyDataPermissionRuleCustomizer autoCompanyDataPermissionRuleCustomizer(BusinessDataPermissionEntityScanner scanner) {
|
||||||
return rule -> scanner.getEntityMetadata().forEach(metadata -> {
|
return rule -> scanner.getEntityMetadata().forEach(metadata -> {
|
||||||
|
|||||||
@@ -28,6 +28,14 @@ import java.util.*;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class BusinessDataPermissionEntityScanner {
|
public class BusinessDataPermissionEntityScanner {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 临时排除的包前缀(物流模块 DO,不参与数据权限扫描)
|
||||||
|
*/
|
||||||
|
private static final Set<String> EXCLUDED_PACKAGE_PREFIXES = Set.of(
|
||||||
|
"com.zt.plat.module.backendlogistics",
|
||||||
|
"com.zt.plat.module.erp",
|
||||||
|
"com.zt.plat.framework.mybatis.core.dataobject.BusinessBaseDO");
|
||||||
|
|
||||||
private final Set<String> basePackages;
|
private final Set<String> basePackages;
|
||||||
private final ClassLoader classLoader;
|
private final ClassLoader classLoader;
|
||||||
|
|
||||||
@@ -70,6 +78,9 @@ public class BusinessDataPermissionEntityScanner {
|
|||||||
if (!StringUtils.hasText(className)) {
|
if (!StringUtils.hasText(className)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (isExcludedPackage(className)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
Class<?> clazz = ClassUtils.forName(className, classLoader);
|
Class<?> clazz = ClassUtils.forName(className, classLoader);
|
||||||
if (clazz == BusinessBaseDO.class || !BusinessBaseDO.class.isAssignableFrom(clazz)) {
|
if (clazz == BusinessBaseDO.class || !BusinessBaseDO.class.isAssignableFrom(clazz)) {
|
||||||
@@ -92,6 +103,15 @@ public class BusinessDataPermissionEntityScanner {
|
|||||||
return new ArrayList<>(metadataMap.values());
|
return new ArrayList<>(metadataMap.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isExcludedPackage(String className) {
|
||||||
|
for (String prefix : EXCLUDED_PACKAGE_PREFIXES) {
|
||||||
|
if (className.startsWith(prefix)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private EntityMetadata buildMetadata(Class<? extends BusinessBaseDO> entityClass) {
|
private EntityMetadata buildMetadata(Class<? extends BusinessBaseDO> entityClass) {
|
||||||
String tableName = resolveTableName(entityClass);
|
String tableName = resolveTableName(entityClass);
|
||||||
if (!StringUtils.hasText(tableName)) {
|
if (!StringUtils.hasText(tableName)) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.zt.plat.framework.datapermission.core.rule.dept;
|
|||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||||
import com.zt.plat.framework.common.biz.system.permission.PermissionCommonApi;
|
import com.zt.plat.framework.common.biz.system.permission.PermissionCommonApi;
|
||||||
import com.zt.plat.framework.common.biz.system.permission.dto.DeptDataPermissionRespDTO;
|
import com.zt.plat.framework.common.biz.system.permission.dto.DeptDataPermissionRespDTO;
|
||||||
import com.zt.plat.framework.common.enums.UserTypeEnum;
|
import com.zt.plat.framework.common.enums.UserTypeEnum;
|
||||||
@@ -14,7 +15,7 @@ import com.zt.plat.framework.mybatis.core.util.MyBatisUtils;
|
|||||||
import com.zt.plat.framework.security.core.LoginUser;
|
import com.zt.plat.framework.security.core.LoginUser;
|
||||||
import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils;
|
import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils;
|
||||||
import com.zt.plat.framework.tenant.core.context.CompanyContextHolder;
|
import com.zt.plat.framework.tenant.core.context.CompanyContextHolder;
|
||||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
import com.zt.plat.framework.tenant.core.context.DeptContextHolder;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.sf.jsqlparser.expression.Alias;
|
import net.sf.jsqlparser.expression.Alias;
|
||||||
@@ -108,6 +109,11 @@ public class DeptDataPermissionRule implements DataPermissionRule {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 显式忽略部门数据权限时直接放行
|
||||||
|
if (DeptContextHolder.shouldIgnore()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// 获得数据权限
|
// 获得数据权限
|
||||||
DeptDataPermissionRespDTO deptDataPermission = loginUser.getContext(CONTEXT_KEY, DeptDataPermissionRespDTO.class);
|
DeptDataPermissionRespDTO deptDataPermission = loginUser.getContext(CONTEXT_KEY, DeptDataPermissionRespDTO.class);
|
||||||
// 从上下文中拿不到,则调用逻辑进行获取
|
// 从上下文中拿不到,则调用逻辑进行获取
|
||||||
@@ -136,6 +142,20 @@ public class DeptDataPermissionRule implements DataPermissionRule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 若存在部门上下文,优先使用上下文中的单一部门,必要时校验公司一致性
|
||||||
|
Long ctxDeptId = DeptContextHolder.getDeptId();
|
||||||
|
if (ctxDeptId != null && ctxDeptId > 0L) {
|
||||||
|
Long currentCompanyId = CompanyContextHolder.getCompanyId();
|
||||||
|
Long ctxCompanyId = DeptContextHolder.getCompanyId();
|
||||||
|
Long compareCompanyId = ctxCompanyId != null ? ctxCompanyId : currentCompanyId;
|
||||||
|
if (currentCompanyId != null && currentCompanyId > 0L
|
||||||
|
&& compareCompanyId != null && !currentCompanyId.equals(compareCompanyId)) {
|
||||||
|
log.warn("[getExpression][LoginUser({}) Table({}/{}) DeptContextHolder company mismatch: currentCompanyId={}, ctxCompanyId={}, ctxDeptId={}, source=DeptContextHolder]",
|
||||||
|
JsonUtils.toJsonString(loginUser), tableName, tableAlias == null ? null : tableAlias.getName(),
|
||||||
|
currentCompanyId, compareCompanyId, ctxDeptId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 情况一,如果是 ALL 可查看全部,则无需拼接条件
|
// 情况一,如果是 ALL 可查看全部,则无需拼接条件
|
||||||
if (deptDataPermission.getAll()) {
|
if (deptDataPermission.getAll()) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,61 @@
|
|||||||
|
package com.zt.plat.framework.tenant.core.context;
|
||||||
|
|
||||||
|
import com.alibaba.ttl.TransmittableThreadLocal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 部门上下文 Holder,使用 {@link TransmittableThreadLocal} 支持在线程池/异步场景下的上下文传递。
|
||||||
|
*
|
||||||
|
* 包含当前部门编号、所属公司编号以及是否忽略部门数据权限的标识。
|
||||||
|
*/
|
||||||
|
public class DeptContextHolder {
|
||||||
|
|
||||||
|
/** 当前部门编号 */
|
||||||
|
private static final ThreadLocal<Long> DEPT_ID = new TransmittableThreadLocal<>();
|
||||||
|
/** 当前部门所属公司编号(用于一致性校验) */
|
||||||
|
private static final ThreadLocal<Long> COMPANY_ID = new TransmittableThreadLocal<>();
|
||||||
|
/** 是否忽略部门数据权限 */
|
||||||
|
private static final ThreadLocal<Boolean> IGNORE = new TransmittableThreadLocal<>();
|
||||||
|
|
||||||
|
public static Long getDeptId() {
|
||||||
|
return DEPT_ID.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Long getCompanyId() {
|
||||||
|
return COMPANY_ID.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置部门与所属公司编号。
|
||||||
|
*/
|
||||||
|
public static void setContext(Long deptId, Long companyId) {
|
||||||
|
DEPT_ID.set(deptId);
|
||||||
|
COMPANY_ID.set(companyId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setDeptId(Long deptId) {
|
||||||
|
DEPT_ID.set(deptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setCompanyId(Long companyId) {
|
||||||
|
COMPANY_ID.set(companyId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean hasDeptId() {
|
||||||
|
Long deptId = DEPT_ID.get();
|
||||||
|
return deptId != null && deptId > 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setIgnore(Boolean ignore) {
|
||||||
|
IGNORE.set(ignore);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean shouldIgnore() {
|
||||||
|
return Boolean.TRUE.equals(IGNORE.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clear() {
|
||||||
|
DEPT_ID.remove();
|
||||||
|
COMPANY_ID.remove();
|
||||||
|
IGNORE.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user