mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-08 04:39:00 +08:00
refactor(data): 支持多角色数据权限计算
This commit is contained in:
1 parent
59ebbb65de
commit
fddf156651
3 files changed
+107
-208
No files matched your search
+65
-59
@@ -20,73 +20,79 @@ import java.util.Map;
|
||||
*/
|
||||
public class DataScopeInnerInterceptor implements DataScopeInterceptor {
|
||||
|
||||
@Setter
|
||||
private DataScopeHandle dataScopeHandle;
|
||||
@Setter
|
||||
private DataScopeHandle dataScopeHandle;
|
||||
|
||||
@Override
|
||||
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds,
|
||||
ResultHandler resultHandler, BoundSql boundSql) {
|
||||
PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
|
||||
@Override
|
||||
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds,
|
||||
ResultHandler resultHandler, BoundSql boundSql) {
|
||||
PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
|
||||
|
||||
String originalSql = boundSql.getSql();
|
||||
Object parameterObject = boundSql.getParameterObject();
|
||||
String originalSql = boundSql.getSql();
|
||||
Object parameterObject = boundSql.getParameterObject();
|
||||
|
||||
// 查找参数中包含DataScope类型的参数
|
||||
DataScope dataScope = findDataScopeObject(parameterObject);
|
||||
if (dataScope == null) {
|
||||
return;
|
||||
}
|
||||
// 查找参数中包含DataScope类型的参数
|
||||
DataScope dataScope = findDataScopeObject(parameterObject);
|
||||
if (dataScope == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 返回true 不拦截直接返回原始 SQL (只针对 * 查询)
|
||||
if (dataScopeHandle.calcScope(dataScope) && DataScopeFuncEnum.ALL.equals(dataScope.getFunc())) {
|
||||
return;
|
||||
}
|
||||
// 返回true 不拦截直接返回原始 SQL (只针对 * 查询)
|
||||
if (DataScopeFuncEnum.ALL.equals(dataScope.getFunc()) && dataScopeHandle.calcScope(dataScope)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 返回true 不拦截直接返回原始 SQL (只针对 COUNT 查询)
|
||||
if (dataScopeHandle.calcScope(dataScope) && DataScopeFuncEnum.COUNT.equals(dataScope.getFunc())) {
|
||||
mpBs.sql(String.format("SELECT %s FROM (%s) temp_data_scope", dataScope.getFunc().getType(), originalSql));
|
||||
return;
|
||||
}
|
||||
// 返回true 不拦截直接返回原始 SQL (只针对 COUNT 查询)
|
||||
if (DataScopeFuncEnum.COUNT.equals(dataScope.getFunc()) && dataScopeHandle.calcScope(dataScope)) {
|
||||
mpBs.sql(String.format("SELECT %s FROM (%s) temp_data_scope", dataScope.getFunc().getType(), originalSql));
|
||||
return;
|
||||
}
|
||||
|
||||
List<Long> deptIds = dataScope.getDeptList();
|
||||
List<Long> deptIds = dataScope.getDeptList();
|
||||
|
||||
// 1.无数据权限限制,则直接返回 0 条数据
|
||||
if (CollUtil.isEmpty(deptIds) && StrUtil.isBlank(dataScope.getUsername())) {
|
||||
originalSql = String.format("SELECT %s FROM (%s) temp_data_scope WHERE 1 = 2",
|
||||
dataScope.getFunc().getType(), originalSql);
|
||||
}
|
||||
// 2.如果为本人权限则走下面
|
||||
else if (StrUtil.isNotBlank(dataScope.getUsername())) {
|
||||
originalSql = String.format("SELECT %s FROM (%s) temp_data_scope WHERE temp_data_scope.%s = '%s'",
|
||||
dataScope.getFunc().getType(), originalSql, dataScope.getScopeUserName(), dataScope.getUsername());
|
||||
}
|
||||
// 3.都没有,则是其他权限,走下面
|
||||
else {
|
||||
String join = CollectionUtil.join(deptIds, ",");
|
||||
originalSql = String.format("SELECT %s FROM (%s) temp_data_scope WHERE temp_data_scope.%s IN (%s)",
|
||||
dataScope.getFunc().getType(), originalSql, dataScope.getScopeDeptName(), join);
|
||||
}
|
||||
// 1.无数据权限限制,则直接返回 0 条数据
|
||||
if (CollUtil.isEmpty(deptIds) && StrUtil.isBlank(dataScope.getUsername())) {
|
||||
originalSql = String.format("SELECT %s FROM (%s) temp_data_scope WHERE 1 = 2",
|
||||
dataScope.getFunc().getType(), originalSql);
|
||||
}
|
||||
// 2.如果为本人权限 + 部门权限控制
|
||||
else if (StrUtil.isNotBlank(dataScope.getUsername()) && CollUtil.isNotEmpty(deptIds)) {
|
||||
String join = CollectionUtil.join(deptIds, ",");
|
||||
originalSql = String.format("SELECT %s FROM (%s) temp_data_scope WHERE temp_data_scope.%s = '%s' OR temp_data_scope.%s IN (%s)",
|
||||
dataScope.getFunc().getType(), originalSql, dataScope.getScopeUserName(), dataScope.getUsername(), dataScope.getScopeDeptName(), join);
|
||||
}
|
||||
// 3. 如果为本人
|
||||
else if (StrUtil.isNotBlank(dataScope.getUsername())) {
|
||||
originalSql = String.format("SELECT %s FROM (%s) temp_data_scope WHERE temp_data_scope.%s = '%s'",
|
||||
dataScope.getFunc().getType(), originalSql, dataScope.getScopeUserName(), dataScope.getUsername());
|
||||
}
|
||||
// 4.部门权限控制
|
||||
else {
|
||||
String join = CollectionUtil.join(deptIds, ",");
|
||||
originalSql = String.format("SELECT %s FROM (%s) temp_data_scope WHERE temp_data_scope.%s IN (%s)",
|
||||
dataScope.getFunc().getType(), originalSql, dataScope.getScopeDeptName(), join);
|
||||
}
|
||||
|
||||
mpBs.sql(originalSql);
|
||||
}
|
||||
mpBs.sql(originalSql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找参数是否包括DataScope对象
|
||||
* @param parameterObj 参数列表
|
||||
* @return DataScope
|
||||
*/
|
||||
private DataScope findDataScopeObject(Object parameterObj) {
|
||||
if (parameterObj instanceof DataScope) {
|
||||
return (DataScope) parameterObj;
|
||||
}
|
||||
else if (parameterObj instanceof Map) {
|
||||
for (Object val : ((Map<?, ?>) parameterObj).values()) {
|
||||
if (val instanceof DataScope) {
|
||||
return (DataScope) val;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* 查找参数是否包括DataScope对象
|
||||
*
|
||||
* @param parameterObj 参数列表
|
||||
* @return DataScope
|
||||
*/
|
||||
private DataScope findDataScopeObject(Object parameterObj) {
|
||||
if (parameterObj instanceof DataScope) {
|
||||
return (DataScope) parameterObj;
|
||||
} else if (parameterObj instanceof Map) {
|
||||
for (Object val : ((Map<?, ?>) parameterObj).values()) {
|
||||
if (val instanceof DataScope) {
|
||||
return (DataScope) val;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+42
-28
@@ -30,39 +30,53 @@ import lombok.Getter;
|
||||
@AllArgsConstructor
|
||||
public enum DataScopeTypeEnum {
|
||||
|
||||
/**
|
||||
* 查询全部数据
|
||||
*/
|
||||
ALL(0, "全部"),
|
||||
/**
|
||||
* 查询全部数据
|
||||
*/
|
||||
ALL(0, "全部"),
|
||||
|
||||
/**
|
||||
* 自定义
|
||||
*/
|
||||
CUSTOM(1, "自定义"),
|
||||
/**
|
||||
* 自定义
|
||||
*/
|
||||
CUSTOM(1, "自定义"),
|
||||
|
||||
/**
|
||||
* 本级及子级
|
||||
*/
|
||||
OWN_CHILD_LEVEL(2, "本级及子级"),
|
||||
/**
|
||||
* 本级及子级
|
||||
*/
|
||||
OWN_CHILD_LEVEL(2, "本级及子级"),
|
||||
|
||||
/**
|
||||
* 本级
|
||||
*/
|
||||
OWN_LEVEL(3, "本级"),
|
||||
/**
|
||||
* 本级
|
||||
*/
|
||||
OWN_LEVEL(3, "本级"),
|
||||
|
||||
/**
|
||||
* 本人
|
||||
*/
|
||||
SELF_LEVEL(4, "本人");
|
||||
/**
|
||||
* 本人
|
||||
*/
|
||||
SELF_LEVEL(4, "本人");
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private final int type;
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private final int type;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private final String description;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private final String description;
|
||||
|
||||
/**
|
||||
* 按类型获取
|
||||
*
|
||||
* @param dsType DS 型
|
||||
* @return {@link DataScopeTypeEnum }
|
||||
*/
|
||||
public static DataScopeTypeEnum getByType(Integer dsType) {
|
||||
for (DataScopeTypeEnum value : DataScopeTypeEnum.values()) {
|
||||
if (value.getType() == dsType) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
-121
@@ -1,121 +0,0 @@
|
||||
/*
|
||||
* 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.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysDept;
|
||||
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.core.constant.enums.UserTypeEnum;
|
||||
import com.pig4cloud.pigx.common.core.util.RetOps;
|
||||
import com.pig4cloud.pigx.common.security.service.PigxUser;
|
||||
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2019-09-07
|
||||
* <p>
|
||||
* 默认data scope 判断处理器
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class PigxDefaultDatascopeHandle implements DataScopeHandle {
|
||||
|
||||
private final RemoteDataScopeService dataScopeService;
|
||||
|
||||
/**
|
||||
* 计算用户数据权限
|
||||
* @param dataScope 数据权限范围
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Boolean calcScope(DataScope dataScope) {
|
||||
PigxUser user = SecurityUtils.getUser();
|
||||
// toc 客户端不进行数据权限
|
||||
if (UserTypeEnum.TOC.getStatus().equals(user.getUserType())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
List<String> roleIdList = user.getAuthorities()
|
||||
.stream()
|
||||
.map(GrantedAuthority::getAuthority)
|
||||
.filter(authority -> authority.startsWith(SecurityConstants.ROLE))
|
||||
.map(authority -> authority.split(StrUtil.UNDERLINE)[1])
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<Long> deptList = dataScope.getDeptList();
|
||||
|
||||
// 当前用户的角色为空 , 返回false
|
||||
if (CollectionUtil.isEmpty(roleIdList)) {
|
||||
return false;
|
||||
}
|
||||
// @formatter:off
|
||||
SysRole role = RetOps.of(dataScopeService.getRoleList(roleIdList))
|
||||
.getData()
|
||||
.orElseGet(Collections::emptyList)
|
||||
.stream()
|
||||
.min(Comparator.comparingInt(SysRole::getDsType)).orElse(null);
|
||||
// @formatter:on
|
||||
// 角色有可能已经删除了
|
||||
if (role == null) {
|
||||
return false;
|
||||
}
|
||||
Integer dsType = role.getDsType();
|
||||
// 查询全部
|
||||
if (DataScopeTypeEnum.ALL.getType() == dsType) {
|
||||
return true;
|
||||
}
|
||||
// 自定义
|
||||
if (DataScopeTypeEnum.CUSTOM.getType() == dsType && StrUtil.isNotBlank(role.getDsScope())) {
|
||||
String dsScope = role.getDsScope();
|
||||
deptList
|
||||
.addAll(Arrays.stream(dsScope.split(StrUtil.COMMA)).map(Long::parseLong).collect(Collectors.toList()));
|
||||
}
|
||||
// 查询本级及其下级
|
||||
if (DataScopeTypeEnum.OWN_CHILD_LEVEL.getType() == dsType) {
|
||||
// @formatter:off
|
||||
List<Long> deptIdList = RetOps.of(dataScopeService.getDescendantList(user.getDeptId()))
|
||||
.getData()
|
||||
.orElseGet(Collections::emptyList)
|
||||
.stream()
|
||||
.map(SysDept::getDeptId).collect(Collectors.toList());
|
||||
// @formatter:on
|
||||
deptList.addAll(deptIdList);
|
||||
}
|
||||
// 只查询本级
|
||||
if (DataScopeTypeEnum.OWN_LEVEL.getType() == dsType) {
|
||||
deptList.add(user.getDeptId());
|
||||
}
|
||||
|
||||
// 只查询本人
|
||||
if (DataScopeTypeEnum.SELF_LEVEL.getType() == dsType) {
|
||||
dataScope.setUsername(user.getUsername());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user