From 03ae63a2b9432ddbbae99417b608b5c4a26a526e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B7=E5=86=B7?= Date: Sat, 7 Sep 2019 20:18:19 +0800 Subject: [PATCH] =?UTF-8?q?:clown=5Fface:=20=20=E5=A2=9E=E5=BC=BA=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=9D=83=E9=99=90=20=E6=94=AF=E6=8C=81=E8=B7=A8?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/datascope/DataScopeHandle.java | 37 ++++++++ .../data/datascope/DataScopeInterceptor.java | 54 ++---------- .../datascope/PigxDefaultDatascopeHandle.java | 88 +++++++++++++++++++ .../data/mybatis/MybatisPlusConfig.java | 18 +++- .../api/feign/RemoteDataScopeService.java | 58 ++++++++++++ .../admin/controller/SysDeptController.java | 16 ++++ .../admin/controller/SysRoleController.java | 12 +++ 7 files changed, 233 insertions(+), 50 deletions(-) create mode 100644 pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeHandle.java create mode 100644 pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/PigxDefaultDatascopeHandle.java create mode 100644 pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteDataScopeService.java 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)); + } }