根据角色信息查询拥有的用户数据
@Component
public class DataScopeHandle {
@Resource
@Lazy
private IOrganizationClient organizationClient;
@Resource
@Lazy
private IUserClient userClient;
public T getCustomer(Class clazz) {
try {
OAuth2Authentication auth = (OAuth2Authentication) SecurityContextHolder.getContext()
.getAuthentication();
if(auth!=null){
OAuth2Request oAuth2Request = auth.getOAuth2Request();
oAuth2Request.getClientId();
Object map = auth.getUserAuthentication().getDetails();
return JSONObject.parseObject(JSONObject.toJSONString(map), clazz);
}
}catch (Exception e){
}
return null;
}
public List calcScope() {
List data = new ArrayList<>();
// 获取当前的用户
OauthInfo oauthInfo = getCustomer(OauthInfo.class);
List deptIds = new ArrayList<>();
if(oauthInfo==null){
return data;
}
// 当前用户的角色为空
if (oauthInfo.getRoles()==null||oauthInfo.getRoles().size()<1) {
return null;
}
Integer dsType = DataScopeTypeEnum.OWN.getType();
RoleDataParam param = new RoleDataParam();
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
param.setResourceUrl(request.getContextPath()+request.getServletPath());
param.setRoleId(oauthInfo.getRoles());
Result> resultData = userClient.getRoleResource(param);
List roleData = resultData.getData();
if (roleData.size()<1){
dsType = DataScopeTypeEnum.ALL.getType();
}
for (RoleResource item:roleData
) {
Integer index = item.getDataScope()==null?0:item.getDataScope();
if (dsType> index){
dsType=item.getDataScope();
}
}
// 查询全部
if (DataScopeTypeEnum.ALL.getType() == dsType) {
return data;
}
// 自定义
if (DataScopeTypeEnum.CUSTOM.getType() == dsType) {
}
// 查询本级及其下级
if (DataScopeTypeEnum.OWN_CHILD_LEVEL.getType() == dsType) {
Long l = oauthInfo.getOrganizationId();
Result result =organizationClient.getOrganizationList(oauthInfo.getOrganizationId());
if (!result.isSuccess()){
throw new RuntimeException(result.getMsg());
}
List list =new ArrayList<>();
Organization organization = result.getData();
list.add(organization.getId());
getOrganization(list, organization);
Result> result1 = userClient.getUserList(list);
data.addAll(result1.getData().stream()
.map(User::getUserNo).collect(Collectors.toList()));
}
// 只查询本级
if (DataScopeTypeEnum.OWN_LEVEL.getType() == dsType) {
Long deptId = oauthInfo.getOrganizationId();
deptIds.add(deptId);
Result> result = userClient.getUserList(deptIds);
data.addAll(result.getData().stream()
.map(User::getUserNo).collect(Collectors.toList()));
}
// 只查询本级
if (DataScopeTypeEnum.OWN.getType() == dsType) {
data.add((oauthInfo.getUserNo()));
}
return data;
}
private void getOrganization(List list, Organization organization) {
if (organization.getTreeList()!=null&&organization.getTreeList().size()>0){
for (Organization item: organization.getTreeList()
) {
list.add(item.getId());
getOrganization(list,item);
}
}
}
}
查询处理
public class DataScopeInnerInterceptor implements InnerInterceptor {
@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);
String originalSql = boundSql.getSql();
//采用判断方法注解方式进行数据权限
Class> clazz = null;
try {
//获取Mapper类
clazz = Class.forName( ms.getId().substring(0, ms.getId().lastIndexOf(".")));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 获取方法名
String methodName = ms.getId().substring(ms.getId().lastIndexOf(".") + 1);
Method[] methods = clazz.getMethods();
//遍历类的方法
for (Method method : methods) {
DataPermission annotation = method.getAnnotation(DataPermission.class);
//判断是否存在注解且方法名一致
if (annotation!=null&&methodName.equals(method.getName())){
String scopeName = annotation.field();
// 优先获取赋值数据
List data = dataScopeHandle.calcScope();
if (data==null) {
//说明没关联角色 返回空数据
originalSql = String.format("SELECT * FROM (%s) temp_data_scope WHERE 1 = 2",originalSql);
}else if (data.size()>0) {
String join = StringUtils.join(data.toArray(),',');
originalSql = String.format("SELECT * FROM (%s) temp_data_scope WHERE temp_data_scope.%s IN (%s)",
originalSql, scopeName, join);
}
}
}
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;
}
}
枚举
@Getter
@AllArgsConstructor
public enum DataScopeTypeEnum {
/**
* 查询全部数据
*/
ALL(0, "全部"),
/**
* 自定义
*/
CUSTOM(1, "自定义"),
/**
* 部门及以下数据权限
*/
OWN_CHILD_LEVEL(2, "部门及以下数据权限"),
/**
* 部门数据权限
*/
OWN_LEVEL(3, "部门数据权限"),
/**
* 仅本人数据权限
*/
OWN(4,"仅本人数据权限");
/**
* 类型
*/
private final int type;
/**
* 描述
*/
private final String description;
}
注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface DataPermission {
String field() default "create_no";
}
注入
@EnableTransactionManagement
@Configuration
public class MybatisPlusConfig {
@Resource
private DataScopeHandle dataScopeHandle;
/**
* 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 数据权限-新
DataScopeInnerInterceptor dataScopeInnerInterceptor = new DataScopeInnerInterceptor();
dataScopeInnerInterceptor.setDataScopeHandle(dataScopeHandle);
interceptor.addInnerInterceptor(dataScopeInnerInterceptor);
//分页要在权限后面
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
//数据库类型
paginationInnerInterceptor.setDbType(DbType.MYSQL);
//溢出总页数后是否进行处理
paginationInnerInterceptor.setOverflow(true);
interceptor.addInnerInterceptor(paginationInnerInterceptor);
return interceptor;
}
//这个是扩展接口方法的 可以删除
@Bean
public MySqlInjector sqlInjector() {
return new MySqlInjector();
}
@Bean
public ConfigurationCustomizer configurationCustomizer() {
return configuration -> configuration.setUseDeprecatedExecutor(false);
}
}
使用时在对应的查询接口处添加注解
@DataPermission
List