diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeHandle.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeHandle.java
new file mode 100644
index 000000000..011607099
--- /dev/null
+++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeHandle.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018-2025, lengleng All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the pig4cloud.com developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: lengleng (wangiegie@gmail.com)
+ */
+
+package com.pig4cloud.pigx.common.data.datascope;
+
+import java.util.List;
+
+/**
+ * @author lengleng
+ * @date 2019-09-07
+ *
+ * data scope 判断处理器,抽象服务扩展
+ */
+public interface DataScopeHandle {
+
+ /**
+ * 计算用户数据权限
+ *
+ * @param deptList
+ * @return
+ */
+ Boolean calcScope(List deptList);
+}
diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeInterceptor.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeInterceptor.java
index 2c80f9386..7b0b262d6 100644
--- a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeInterceptor.java
+++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeInterceptor.java
@@ -19,15 +19,8 @@ package com.pig4cloud.pigx.common.data.datascope;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.db.Db;
-import cn.hutool.db.Entity;
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
import com.baomidou.mybatisplus.extension.handlers.AbstractSqlParserHandler;
-import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
-import com.pig4cloud.pigx.common.data.enums.DataScopeTypeEnum;
-import com.pig4cloud.pigx.common.security.service.PigxUser;
-import com.pig4cloud.pigx.common.security.util.SecurityUtils;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
@@ -38,12 +31,11 @@ import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
-import org.springframework.security.core.GrantedAuthority;
-import javax.sql.DataSource;
import java.sql.Connection;
-import java.util.*;
-import java.util.stream.Collectors;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
/**
@@ -56,7 +48,7 @@ import java.util.stream.Collectors;
@AllArgsConstructor
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class DataScopeInterceptor extends AbstractSqlParserHandler implements Interceptor {
- private final DataSource dataSource;
+ private final DataScopeHandle dataScopeHandle;
@Override
@SneakyThrows
@@ -83,41 +75,8 @@ public class DataScopeInterceptor extends AbstractSqlParserHandler implements In
String scopeName = dataScope.getScopeName();
List deptIds = dataScope.getDeptIds();
// 优先获取赋值数据
- if (CollUtil.isEmpty(deptIds)) {
- PigxUser user = SecurityUtils.getUser();
- List roleIdList = user.getAuthorities()
- .stream().map(GrantedAuthority::getAuthority)
- .filter(authority -> authority.startsWith(SecurityConstants.ROLE))
- .map(authority -> authority.split(StrUtil.UNDERLINE)[1])
- .collect(Collectors.toList());
-
- Entity query = Db.use(dataSource)
- .query("SELECT * FROM sys_role where role_id IN (" + CollUtil.join(roleIdList, ",") + ")")
- .stream().min(Comparator.comparingInt(o -> o.getInt("ds_type"))).get();
-
- Integer dsType = query.getInt("ds_type");
- // 查询全部
- if (DataScopeTypeEnum.ALL.getType() == dsType) {
- return invocation.proceed();
- }
- // 自定义
- if (DataScopeTypeEnum.CUSTOM.getType() == dsType) {
- String dsScope = query.getStr("ds_scope");
- deptIds.addAll(Arrays.stream(dsScope.split(StrUtil.COMMA))
- .map(Integer::parseInt).collect(Collectors.toList()));
- }
- // 查询本级及其下级
- if (DataScopeTypeEnum.OWN_CHILD_LEVEL.getType() == dsType) {
- List deptIdList = Db.use(dataSource)
- .findBy("sys_dept_relation", "ancestor", user.getDeptId())
- .stream().map(entity -> entity.getInt("descendant"))
- .collect(Collectors.toList());
- deptIds.addAll(deptIdList);
- }
- // 只查询本级
- if (DataScopeTypeEnum.OWN_LEVEL.getType() == dsType) {
- deptIds.add(user.getDeptId());
- }
+ if (CollUtil.isEmpty(deptIds) && dataScopeHandle.calcScope(deptIds)) {
+ return invocation.proceed();
}
String join = CollectionUtil.join(deptIds, ",");
originalSql = "select * from (" + originalSql + ") temp_data_scope where temp_data_scope." + scopeName + " in (" + join + ")";
@@ -125,6 +84,7 @@ public class DataScopeInterceptor extends AbstractSqlParserHandler implements In
return invocation.proceed();
}
+
/**
* 生成拦截对象的代理
*
diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/PigxDefaultDatascopeHandle.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/PigxDefaultDatascopeHandle.java
new file mode 100644
index 000000000..2a1191256
--- /dev/null
+++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/PigxDefaultDatascopeHandle.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2018-2025, lengleng All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the pig4cloud.com developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: lengleng (wangiegie@gmail.com)
+ */
+
+package com.pig4cloud.pigx.common.data.datascope;
+
+import cn.hutool.core.util.StrUtil;
+import com.pig4cloud.pigx.admin.api.entity.SysDeptRelation;
+import com.pig4cloud.pigx.admin.api.entity.SysRole;
+import com.pig4cloud.pigx.admin.api.feign.RemoteDataScopeService;
+import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
+import com.pig4cloud.pigx.common.data.enums.DataScopeTypeEnum;
+import com.pig4cloud.pigx.common.security.service.PigxUser;
+import com.pig4cloud.pigx.common.security.util.SecurityUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.GrantedAuthority;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author lengleng
+ * @date 2019-09-07
+ *
+ * 默认data scope 判断处理器
+ */
+public class PigxDefaultDatascopeHandle implements DataScopeHandle {
+ @Autowired
+ private RemoteDataScopeService dataScopeService;
+
+ /**
+ * 计算用户数据权限
+ *
+ * @param deptList
+ * @return
+ */
+ @Override
+ public Boolean calcScope(List deptList) {
+ PigxUser user = SecurityUtils.getUser();
+ List roleIdList = user.getAuthorities()
+ .stream().map(GrantedAuthority::getAuthority)
+ .filter(authority -> authority.startsWith(SecurityConstants.ROLE))
+ .map(authority -> authority.split(StrUtil.UNDERLINE)[1])
+ .collect(Collectors.toList());
+
+ SysRole role = dataScopeService.getRoleList(roleIdList).getData().stream()
+ .min(Comparator.comparingInt(SysRole::getDsType)).get();
+
+ Integer dsType = role.getDsType();
+ // 查询全部
+ if (DataScopeTypeEnum.ALL.getType() == dsType) {
+ return true;
+ }
+ // 自定义
+ if (DataScopeTypeEnum.CUSTOM.getType() == dsType) {
+ String dsScope = role.getDsScope();
+ deptList.addAll(Arrays.stream(dsScope.split(StrUtil.COMMA))
+ .map(Integer::parseInt).collect(Collectors.toList()));
+ }
+ // 查询本级及其下级
+ if (DataScopeTypeEnum.OWN_CHILD_LEVEL.getType() == dsType) {
+ List deptIdList = dataScopeService.getDescendantList(user.getDeptId())
+ .getData().stream().map(SysDeptRelation::getDescendant)
+ .collect(Collectors.toList());
+ deptList.addAll(deptIdList);
+ }
+ // 只查询本级
+ if (DataScopeTypeEnum.OWN_LEVEL.getType() == dsType) {
+ deptList.add(user.getDeptId());
+ }
+ return false;
+ }
+}
diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/MybatisPlusConfig.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/MybatisPlusConfig.java
index 2abef06fd..dc6be199e 100644
--- a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/MybatisPlusConfig.java
+++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/MybatisPlusConfig.java
@@ -22,7 +22,9 @@ import com.baomidou.mybatisplus.core.parser.ISqlParser;
import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
+import com.pig4cloud.pigx.common.data.datascope.DataScopeHandle;
import com.pig4cloud.pigx.common.data.datascope.DataScopeInterceptor;
+import com.pig4cloud.pigx.common.data.datascope.PigxDefaultDatascopeHandle;
import com.pig4cloud.pigx.common.data.tenant.PigxTenantHandler;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
@@ -77,16 +79,26 @@ public class MybatisPlusConfig {
return paginationInterceptor;
}
+ /**
+ * pigx 默认数据权限处理
+ *
+ * @return
+ */
+ @Bean
+ @ConditionalOnMissingBean
+ public DataScopeHandle dataScopeHandle() {
+ return new PigxDefaultDatascopeHandle();
+ }
+
/**
* 数据权限插件
*
- * @param dataSource 数据源
* @return DataScopeInterceptor
*/
@Bean
@ConditionalOnMissingBean
- public DataScopeInterceptor dataScopeInterceptor(DataSource dataSource) {
- return new DataScopeInterceptor(dataSource);
+ public DataScopeInterceptor dataScopeInterceptor() {
+ return new DataScopeInterceptor(dataScopeHandle());
}
/**
diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteDataScopeService.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteDataScopeService.java
new file mode 100644
index 000000000..4070e4f9a
--- /dev/null
+++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteDataScopeService.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2018-2025, lengleng All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the pig4cloud.com developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: lengleng (wangiegie@gmail.com)
+ */
+
+package com.pig4cloud.pigx.admin.api.feign;
+
+import com.pig4cloud.pigx.admin.api.entity.SysDeptRelation;
+import com.pig4cloud.pigx.admin.api.entity.SysRole;
+import com.pig4cloud.pigx.common.core.constant.ServiceNameConstants;
+import com.pig4cloud.pigx.common.core.util.R;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.List;
+
+/**
+ * @author lengleng
+ * @date 2019-09-07
+ *
+ * 远程数据权限调用接口
+ */
+@FeignClient(contextId = "remoteDataScopeService", value = ServiceNameConstants.UPMS_SERVICE)
+public interface RemoteDataScopeService {
+
+ /**
+ * 通过角色ID 查询角色列表
+ *
+ * @param roleIdList 角色ID
+ * @return
+ */
+ @PostMapping("/role/getRoleList")
+ R> getRoleList(@RequestBody List roleIdList);
+
+ /**
+ * 获取子级部门
+ *
+ * @param deptId 部门ID
+ * @return
+ */
+ @GetMapping("/dept/getDescendantList/{deptId}")
+ R> getDescendantList(@PathVariable("deptId") Integer deptId);
+}
diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysDeptController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysDeptController.java
index e3aafa619..7f164c7e5 100644
--- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysDeptController.java
+++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysDeptController.java
@@ -19,7 +19,10 @@
package com.pig4cloud.pigx.admin.controller;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pig4cloud.pigx.admin.api.entity.SysDept;
+import com.pig4cloud.pigx.admin.api.entity.SysDeptRelation;
+import com.pig4cloud.pigx.admin.service.SysDeptRelationService;
import com.pig4cloud.pigx.admin.service.SysDeptService;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
@@ -44,6 +47,7 @@ import java.time.LocalDateTime;
@RequestMapping("/dept")
@Api(value = "dept", tags = "部门管理模块")
public class SysDeptController {
+ private final SysDeptRelationService relationService;
private final SysDeptService sysDeptService;
/**
@@ -107,4 +111,16 @@ public class SysDeptController {
sysDept.setUpdateTime(LocalDateTime.now());
return R.ok(sysDeptService.updateDeptById(sysDept));
}
+
+ /**
+ * 查收子级列表
+ *
+ * @return 返回子级
+ */
+ @GetMapping(value = "/getDescendantList/{deptId}")
+ public R getDescendantList(@PathVariable Integer deptId) {
+ return R.ok(relationService.list(Wrappers.lambdaQuery()
+ .eq(SysDeptRelation::getAncestor, deptId)));
+ }
+
}
diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysRoleController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysRoleController.java
index 254a880f4..db9ad7ff8 100644
--- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysRoleController.java
+++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysRoleController.java
@@ -32,6 +32,7 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
+import java.util.List;
/**
* @author lengleng
@@ -130,4 +131,15 @@ public class SysRoleController {
SysRole sysRole = sysRoleService.getById(roleId);
return R.ok(sysRoleMenuService.saveRoleMenus(sysRole.getRoleCode(), roleId, menuIds));
}
+
+ /**
+ * 通过角色ID 查询角色列表
+ *
+ * @param roleIdList 角色ID
+ * @return
+ */
+ @PostMapping("/getRoleList")
+ public R getRoleList(@RequestBody List roleIdList) {
+ return R.ok(sysRoleService.listByIds(roleIdList));
+ }
}