feat:(REQ-2300) 注释数据权限解析,由用户显示的传递解析结果

This commit is contained in:
lilong 2024-06-28 14:56:33 +08:00
parent 92e391b10a
commit 2bf9c7df07
6 changed files with 319 additions and 304 deletions

View File

@ -9,8 +9,9 @@ import static cn.axzo.framework.datapermission.context.DataPermissionContextHold
/** /**
* 上下文中有DataPermissionContext则把数据放在header中 * 上下文中有DataPermissionContext则把数据放在header中
* 根据用户调研结果选择BFF解析规则结果放在上下文由用户显示的把上下文的数据传递到底层服务方便排查问题和使用
*/ */
@Component //@Component
public class DataPermissionFeignInterceptor implements RequestInterceptor { public class DataPermissionFeignInterceptor implements RequestInterceptor {
@Override @Override

View File

@ -11,8 +11,11 @@ import cn.axzo.karma.client.feign.tyr.request.GetMergeMatchDataReq;
import cn.axzo.karma.client.feign.tyr.request.MatchDataObjectReq; import cn.axzo.karma.client.feign.tyr.request.MatchDataObjectReq;
import cn.axzo.karma.client.feign.tyr.response.MatchDataObjectResp; import cn.axzo.karma.client.feign.tyr.response.MatchDataObjectResp;
import cn.axzo.karma.client.feign.tyr.response.MergeMatchDataResp; import cn.axzo.karma.client.feign.tyr.response.MergeMatchDataResp;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.annotation.Pointcut;
@ -37,7 +40,7 @@ import static cn.axzo.framework.datapermission.context.DataPermissionContextHold
@Aspect @Aspect
@Order(100) @Order(100)
@Component @Component
public class DataPermissionPrepareInterceptor { public class DataPermissionInterceptor {
@Lazy @Lazy
@Autowired @Autowired
@ -75,17 +78,21 @@ public class DataPermissionPrepareInterceptor {
/** /**
* 切入含有@DataPermissiont && @RestController 注解的类 * 切入含有@DataPermissiont && @RestController 注解的类
*/ */
@Before(value = "@within(dataPermission) && @within(restController)") @Around(value = "@within(dataPermission) && @within(restController)")
public void classHandler(DataPermission dataPermission, RestController restController) { @SneakyThrows
public Object classHandler(ProceedingJoinPoint pjp, DataPermission dataPermission, RestController restController) {
handle(dataPermission); handle(dataPermission);
return pjp.proceed(pjp.getArgs());
} }
/** /**
* 切入含有@DataPermissiont && @RequestMapping/@PostMapping/@GetMapping/@PutMapping/@DeleteMapping/@PatchMapping 之一注解的方法 * 切入含有@DataPermissiont && @RequestMapping/@PostMapping/@GetMapping/@PutMapping/@DeleteMapping/@PatchMapping 之一注解的方法
*/ */
@Before(value = "@annotation(dataPermission) && mappingAnnotations()") @Around(value = "@annotation(dataPermission) && mappingAnnotations()")
public void methodHandler(DataPermission dataPermission) { @SneakyThrows
public Object methodHandler(ProceedingJoinPoint pjp, DataPermission dataPermission) {
handle(dataPermission); handle(dataPermission);
return pjp.proceed(pjp.getArgs());
} }
public void handle(DataPermission dataPermission) { public void handle(DataPermission dataPermission) {
@ -105,12 +112,12 @@ public class DataPermissionPrepareInterceptor {
// header中有值表示数据权限规则已经被解析只需要获取数据去使用 // header中有值表示数据权限规则已经被解析只需要获取数据去使用
if (StringUtils.isBlank(dataPermissionHeader)) { if (StringUtils.isBlank(dataPermissionHeader)) {
resolveRule(dataPermission); resolveRule(dataPermission);
return; // return;
} }
DataPermissionContextHolder.DataPermissionContext dataPermissionContext = getCachedDataPermission(dataPermissionHeader); // DataPermissionContextHolder.DataPermissionContext dataPermissionContext = getCachedDataPermission(dataPermissionHeader);
dataPermissionContext.setDataPermission(dataPermission); // dataPermissionContext.setDataPermission(dataPermission);
DataPermissionContextHolder.setContext(dataPermissionContext); // DataPermissionContextHolder.setContext(dataPermissionContext);
} }
/** /**

View File

@ -51,286 +51,288 @@ import java.util.Optional;
* @author tanjie@axzo.cn * @author tanjie@axzo.cn
* @date 2024/5/31 11:41 * @date 2024/5/31 11:41
*/ */
@RequiredArgsConstructor //@RequiredArgsConstructor
public class DataPermissionMybatisInterceptor extends JsqlParserSupport implements InnerInterceptor { public class DataPermissionMybatisInterceptor
// extends JsqlParserSupport implements InnerInterceptor
{
private final DataPermissionContextFactory dataPermissionContextFactory; // private final DataPermissionContextFactory dataPermissionContextFactory;
@Override // @Override
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException { // public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
if (!filter()) { // if (!filter()) {
return; // return;
} // }
PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql); // PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
mpBs.sql(parserSingle(mpBs.sql(), null)); // mpBs.sql(parserSingle(mpBs.sql(), null));
} // }
//
@Override // @Override
public void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) { // public void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) {
PluginUtils.MPStatementHandler mpSh = PluginUtils.mpStatementHandler(sh); // PluginUtils.MPStatementHandler mpSh = PluginUtils.mpStatementHandler(sh);
MappedStatement ms = mpSh.mappedStatement(); // MappedStatement ms = mpSh.mappedStatement();
SqlCommandType sct = ms.getSqlCommandType(); // SqlCommandType sct = ms.getSqlCommandType();
// 不管insert // // 不管insert
if (sct == SqlCommandType.UPDATE || sct == SqlCommandType.DELETE) { // if (sct == SqlCommandType.UPDATE || sct == SqlCommandType.DELETE) {
if (!filter()) return; // if (!filter()) return;
if (SqlParserHelper.getSqlParserInfo(ms)) return; // if (SqlParserHelper.getSqlParserInfo(ms)) return;
PluginUtils.MPBoundSql mpBs = mpSh.mPBoundSql(); // PluginUtils.MPBoundSql mpBs = mpSh.mPBoundSql();
mpBs.sql(parserMulti(mpBs.sql(), null)); // mpBs.sql(parserMulti(mpBs.sql(), null));
} // }
} // }
//
@Override // @Override
protected void processSelect(Select select, int index, String sql, Object obj) { // protected void processSelect(Select select, int index, String sql, Object obj) {
processSelectBody(select.getSelectBody()); // processSelectBody(select.getSelectBody());
List<WithItem> withItemsList = select.getWithItemsList(); // List<WithItem> withItemsList = select.getWithItemsList();
if (!CollectionUtils.isEmpty(withItemsList)) { // if (!CollectionUtils.isEmpty(withItemsList)) {
withItemsList.forEach(this::processSelectBody); // withItemsList.forEach(this::processSelectBody);
} // }
} // }
//
protected void processSelectBody(SelectBody selectBody) { // protected void processSelectBody(SelectBody selectBody) {
if (selectBody == null) { // if (selectBody == null) {
return; // return;
} // }
if (selectBody instanceof PlainSelect) { // if (selectBody instanceof PlainSelect) {
processPlainSelect((PlainSelect) selectBody); // processPlainSelect((PlainSelect) selectBody);
} else if (selectBody instanceof WithItem) { // } else if (selectBody instanceof WithItem) {
WithItem withItem = (WithItem) selectBody; // WithItem withItem = (WithItem) selectBody;
processSelectBody(withItem.getSelectBody()); // processSelectBody(withItem.getSelectBody());
} else { // } else {
SetOperationList operationList = (SetOperationList) selectBody; // SetOperationList operationList = (SetOperationList) selectBody;
if (operationList.getSelects() != null && operationList.getSelects().size() > 0) { // if (operationList.getSelects() != null && operationList.getSelects().size() > 0) {
operationList.getSelects().forEach(this::processSelectBody); // operationList.getSelects().forEach(this::processSelectBody);
} // }
} // }
} // }
//
//
/** // /**
* update 语句处理 // * update 语句处理
*/ // */
@Override // @Override
protected void processUpdate(Update update, int index, String sql, Object obj) { // protected void processUpdate(Update update, int index, String sql, Object obj) {
final Table table = update.getTable(); // final Table table = update.getTable();
if (!filter()) { // if (!filter()) {
// 过滤退出执行 // // 过滤退出执行
return; // return;
} // }
update.setWhere(this.andExpression(table, update.getWhere())); // update.setWhere(this.andExpression(table, update.getWhere()));
} // }
//
/** // /**
* delete 语句处理 // * delete 语句处理
*/ // */
@Override // @Override
protected void processDelete(Delete delete, int index, String sql, Object obj) { // protected void processDelete(Delete delete, int index, String sql, Object obj) {
if (!filter()) { // if (!filter()) {
// 过滤退出执行 // // 过滤退出执行
return; // return;
} // }
delete.setWhere(this.andExpression(delete.getTable(), delete.getWhere())); // delete.setWhere(this.andExpression(delete.getTable(), delete.getWhere()));
} // }
//
/** // /**
* delete update 语句 where 处理 // * delete update 语句 where 处理
*/ // */
protected Expression andExpression(Table table, Expression where) { // protected Expression andExpression(Table table, Expression where) {
//
//
DataPermissionContextHolder.DataPermissionContext dataPermissionContext = DataPermissionContextHolder.get(); // DataPermissionContextHolder.DataPermissionContext dataPermissionContext = DataPermissionContextHolder.get();
DataPermission dataPermission = dataPermissionContext.getDataPermission(); // DataPermission dataPermission = dataPermissionContext.getDataPermission();
// 接口未配置注解就不需要自动增加sql // // 接口未配置注解就不需要自动增加sql
if (dataPermission == null) { // if (dataPermission == null) {
return where; // return where;
} // }
//
List<DataPermissionRuleService> byDataPermission = dataPermissionContextFactory.getRuleByDataPermission(); // List<DataPermissionRuleService> byDataPermission = dataPermissionContextFactory.getRuleByDataPermission();
Optional<DataPermissionRuleService> first = byDataPermission.stream().filter(rule -> rule.getTableName().contains(table.getName())).findFirst(); // Optional<DataPermissionRuleService> first = byDataPermission.stream().filter(rule -> rule.getTableName().contains(table.getName())).findFirst();
if (!first.isPresent()) { // if (!first.isPresent()) {
return where; // return where;
} // }
DataPermissionRuleService dataPermissionRuleService = first.get(); // DataPermissionRuleService dataPermissionRuleService = first.get();
Expression ruleExpression = dataPermissionRuleService.getExpression(table.getName(), table.getAlias()); // Expression ruleExpression = dataPermissionRuleService.getExpression(table.getName(), table.getAlias());
//
if (null != where) { // if (null != where) {
if (where instanceof OrExpression) { // if (where instanceof OrExpression) {
return new AndExpression(ruleExpression, new Parenthesis(where)); // return new AndExpression(ruleExpression, new Parenthesis(where));
} else { // } else {
return new AndExpression(ruleExpression, where); // return new AndExpression(ruleExpression, where);
} // }
} // }
return ruleExpression; // return ruleExpression;
} // }
//
//
//
//
//
/** // /**
* 处理 PlainSelect // * 处理 PlainSelect
*/ // */
protected void processPlainSelect(PlainSelect plainSelect) { // protected void processPlainSelect(PlainSelect plainSelect) {
FromItem fromItem = plainSelect.getFromItem(); // FromItem fromItem = plainSelect.getFromItem();
Expression where = plainSelect.getWhere(); // Expression where = plainSelect.getWhere();
processWhereSubSelect(where); // processWhereSubSelect(where);
if (fromItem instanceof Table) { // if (fromItem instanceof Table) {
Table fromTable = (Table) fromItem; // Table fromTable = (Table) fromItem;
if (filter()) { // if (filter()) {
//#1186 github // //#1186 github
plainSelect.setWhere(builderExpression(where, fromTable)); // plainSelect.setWhere(builderExpression(where, fromTable));
} // }
} else { // } else {
processFromItem(fromItem); // processFromItem(fromItem);
} // }
List<Join> joins = plainSelect.getJoins(); // List<Join> joins = plainSelect.getJoins();
if (joins != null && joins.size() > 0) { // if (joins != null && joins.size() > 0) {
joins.forEach(j -> { // joins.forEach(j -> {
processJoin(j); // processJoin(j);
processFromItem(j.getRightItem()); // processFromItem(j.getRightItem());
}); // });
} // }
} // }
//
/** // /**
* 处理where条件内的子查询 // * 处理where条件内的子查询
* <p> // * <p>
* 支持如下: // * 支持如下:
* 1. in // * 1. in
* 2. = // * 2. =
* 3. > // * 3. >
* 4. < // * 4. <
* 5. >= // * 5. >=
* 6. <= // * 6. <=
* 7. <> // * 7. <>
* 8. EXISTS // * 8. EXISTS
* 9. NOT EXISTS // * 9. NOT EXISTS
* <p> // * <p>
* 前提条件: // * 前提条件:
* 1. 子查询必须放在小括号中 // * 1. 子查询必须放在小括号中
* 2. 子查询一般放在比较操作符的右边 // * 2. 子查询一般放在比较操作符的右边
* // *
* @param where where 条件 // * @param where where 条件
*/ // */
protected void processWhereSubSelect(Expression where) { // protected void processWhereSubSelect(Expression where) {
if (where == null) { // if (where == null) {
return; // return;
} // }
if (where instanceof FromItem) { // if (where instanceof FromItem) {
processFromItem((FromItem) where); // processFromItem((FromItem) where);
return; // return;
} // }
if (where.toString().indexOf("SELECT") > 0) { // if (where.toString().indexOf("SELECT") > 0) {
// 有子查询 // // 有子查询
if (where instanceof BinaryExpression) { // if (where instanceof BinaryExpression) {
// 比较符号 , and , or , 等等 // // 比较符号 , and , or , 等等
BinaryExpression expression = (BinaryExpression) where; // BinaryExpression expression = (BinaryExpression) where;
processWhereSubSelect(expression.getLeftExpression()); // processWhereSubSelect(expression.getLeftExpression());
processWhereSubSelect(expression.getRightExpression()); // processWhereSubSelect(expression.getRightExpression());
} else if (where instanceof InExpression) { // } else if (where instanceof InExpression) {
// in // // in
InExpression expression = (InExpression) where; // InExpression expression = (InExpression) where;
ItemsList itemsList = expression.getRightItemsList(); // ItemsList itemsList = expression.getRightItemsList();
if (itemsList instanceof SubSelect) { // if (itemsList instanceof SubSelect) {
processSelectBody(((SubSelect) itemsList).getSelectBody()); // processSelectBody(((SubSelect) itemsList).getSelectBody());
} // }
} else if (where instanceof ExistsExpression) { // } else if (where instanceof ExistsExpression) {
// exists // // exists
ExistsExpression expression = (ExistsExpression) where; // ExistsExpression expression = (ExistsExpression) where;
processWhereSubSelect(expression.getRightExpression()); // processWhereSubSelect(expression.getRightExpression());
} else if (where instanceof NotExpression) { // } else if (where instanceof NotExpression) {
// not exists // // not exists
NotExpression expression = (NotExpression) where; // NotExpression expression = (NotExpression) where;
processWhereSubSelect(expression.getExpression()); // processWhereSubSelect(expression.getExpression());
} else if (where instanceof Parenthesis) { // } else if (where instanceof Parenthesis) {
Parenthesis expression = (Parenthesis) where; // Parenthesis expression = (Parenthesis) where;
processWhereSubSelect(expression.getExpression()); // processWhereSubSelect(expression.getExpression());
} // }
} // }
} // }
//
/** // /**
* 处理子查询等 // * 处理子查询等
*/ // */
protected void processFromItem(FromItem fromItem) { // protected void processFromItem(FromItem fromItem) {
if (fromItem instanceof SubJoin) { // if (fromItem instanceof SubJoin) {
SubJoin subJoin = (SubJoin) fromItem; // SubJoin subJoin = (SubJoin) fromItem;
if (subJoin.getJoinList() != null) { // if (subJoin.getJoinList() != null) {
subJoin.getJoinList().forEach(this::processJoin); // subJoin.getJoinList().forEach(this::processJoin);
} // }
if (subJoin.getLeft() != null) { // if (subJoin.getLeft() != null) {
processFromItem(subJoin.getLeft()); // processFromItem(subJoin.getLeft());
} // }
} else if (fromItem instanceof SubSelect) { // } else if (fromItem instanceof SubSelect) {
SubSelect subSelect = (SubSelect) fromItem; // SubSelect subSelect = (SubSelect) fromItem;
if (subSelect.getSelectBody() != null) { // if (subSelect.getSelectBody() != null) {
processSelectBody(subSelect.getSelectBody()); // processSelectBody(subSelect.getSelectBody());
} // }
} else if (fromItem instanceof ValuesList) { // } else if (fromItem instanceof ValuesList) {
logger.debug("Perform a subquery, if you do not give us feedback"); // logger.debug("Perform a subquery, if you do not give us feedback");
} else if (fromItem instanceof LateralSubSelect) { // } else if (fromItem instanceof LateralSubSelect) {
LateralSubSelect lateralSubSelect = (LateralSubSelect) fromItem; // LateralSubSelect lateralSubSelect = (LateralSubSelect) fromItem;
if (lateralSubSelect.getSubSelect() != null) { // if (lateralSubSelect.getSubSelect() != null) {
SubSelect subSelect = lateralSubSelect.getSubSelect(); // SubSelect subSelect = lateralSubSelect.getSubSelect();
if (subSelect.getSelectBody() != null) { // if (subSelect.getSelectBody() != null) {
processSelectBody(subSelect.getSelectBody()); // processSelectBody(subSelect.getSelectBody());
} // }
} // }
} // }
} // }
//
/** // /**
* 处理联接语句 // * 处理联接语句
*/ // */
protected void processJoin(Join join) { // protected void processJoin(Join join) {
if (join.getRightItem() instanceof Table) { // if (join.getRightItem() instanceof Table) {
Table fromTable = (Table) join.getRightItem(); // Table fromTable = (Table) join.getRightItem();
if (!filter()) { // if (!filter()) {
// 过滤退出执行 // // 过滤退出执行
return; // return;
} // }
join.setOnExpression(builderExpression(join.getOnExpression(), fromTable)); // join.setOnExpression(builderExpression(join.getOnExpression(), fromTable));
} // }
} // }
//
/** // /**
* 处理条件 // * 处理条件
*/ // */
protected Expression builderExpression(Expression currentExpression, Table table) { // protected Expression builderExpression(Expression currentExpression, Table table) {
//
DataPermissionContextHolder.DataPermissionContext dataPermissionContext = DataPermissionContextHolder.get(); // DataPermissionContextHolder.DataPermissionContext dataPermissionContext = DataPermissionContextHolder.get();
DataPermission dataPermission = dataPermissionContext.getDataPermission(); // DataPermission dataPermission = dataPermissionContext.getDataPermission();
//
// 接口未配置注解就不需要自动增加sql // // 接口未配置注解就不需要自动增加sql
if (dataPermission == null) { // if (dataPermission == null) {
return currentExpression; // return currentExpression;
} // }
//
List<DataPermissionRuleService> byDataPermission = dataPermissionContextFactory.getRuleByDataPermission(); // List<DataPermissionRuleService> byDataPermission = dataPermissionContextFactory.getRuleByDataPermission();
Optional<DataPermissionRuleService> first = byDataPermission.stream().filter(rule -> rule.getTableName().contains(table.getName())).findFirst(); // Optional<DataPermissionRuleService> first = byDataPermission.stream().filter(rule -> rule.getTableName().contains(table.getName())).findFirst();
if (!first.isPresent()) { // if (!first.isPresent()) {
return currentExpression; // return currentExpression;
} // }
DataPermissionRuleService dataPermissionRuleService = first.get(); // DataPermissionRuleService dataPermissionRuleService = first.get();
Expression ruleExpression = dataPermissionRuleService.getExpression(table.getName(), table.getAlias()); // Expression ruleExpression = dataPermissionRuleService.getExpression(table.getName(), table.getAlias());
if (currentExpression == null) { // if (currentExpression == null) {
return ruleExpression; // return ruleExpression;
} // }
if (currentExpression instanceof OrExpression) { // if (currentExpression instanceof OrExpression) {
return new AndExpression(new Parenthesis(currentExpression), ruleExpression); // return new AndExpression(new Parenthesis(currentExpression), ruleExpression);
} else { // } else {
return new AndExpression(currentExpression, ruleExpression); // return new AndExpression(currentExpression, ruleExpression);
} // }
} // }
//
private boolean filter() { // private boolean filter() {
DataPermissionContextHolder.DataPermissionContext dataPermissionContext = DataPermissionContextHolder.get(); // DataPermissionContextHolder.DataPermissionContext dataPermissionContext = DataPermissionContextHolder.get();
if (null == dataPermissionContext // if (null == dataPermissionContext
|| dataPermissionContext.getDataPermission() == null // || dataPermissionContext.getDataPermission() == null
|| !dataPermissionContext.getDataPermission().enable()) { // || !dataPermissionContext.getDataPermission().enable()) {
return false; // return false;
} // }
//
return true; // return true;
} // }
} }

View File

@ -13,20 +13,20 @@ import java.util.List;
* @author tanjie@axzo.cn * @author tanjie@axzo.cn
* @date 2024/5/31 16:34 * @date 2024/5/31 16:34
*/ */
@ConditionalOnBean(MybatisPlusInterceptor.class) //@ConditionalOnBean(MybatisPlusInterceptor.class)
public class DataPermissionConfig { public class DataPermissionConfig {
@Bean // @Bean
@ConditionalOnBean(MybatisPlusInterceptor.class) // @ConditionalOnBean(MybatisPlusInterceptor.class)
public DataPermissionMybatisInterceptor mybatisDataPermissionInterceptor(MybatisPlusInterceptor mybatisPlusInterceptor, DataPermissionContextFactory dataPermissionContextFactory) { // public DataPermissionMybatisInterceptor mybatisDataPermissionInterceptor(MybatisPlusInterceptor mybatisPlusInterceptor, DataPermissionContextFactory dataPermissionContextFactory) {
DataPermissionMybatisInterceptor dataPermissionMybatisInterceptor = new DataPermissionMybatisInterceptor(dataPermissionContextFactory); // DataPermissionMybatisInterceptor dataPermissionMybatisInterceptor = new DataPermissionMybatisInterceptor(dataPermissionContextFactory);
mybatisPlusInterceptor.addInnerInterceptor(dataPermissionMybatisInterceptor); // mybatisPlusInterceptor.addInnerInterceptor(dataPermissionMybatisInterceptor);
return dataPermissionMybatisInterceptor; // return dataPermissionMybatisInterceptor;
} // }
//
//
@Bean // @Bean
public DataPermissionContextFactory dataPermissionRuleFactory(List<DataPermissionRuleService> rules) { // public DataPermissionContextFactory dataPermissionRuleFactory(List<DataPermissionRuleService> rules) {
return new DataPermissionContextFactory(rules); // return new DataPermissionContextFactory(rules);
} // }
} }

View File

@ -9,7 +9,7 @@ import java.util.List;
* @author tanjie@axzo.cn * @author tanjie@axzo.cn
* @date 2024/5/31 17:58 * @date 2024/5/31 17:58
*/ */
@AllArgsConstructor //@AllArgsConstructor
public class DataPermissionContextFactory { public class DataPermissionContextFactory {
List<DataPermissionRuleService> rules; List<DataPermissionRuleService> rules;

View File

@ -61,6 +61,11 @@ public class DataPermissionContextHolder {
* 解析后的部门id * 解析后的部门id
*/ */
private Set<Long> nodeIds; private Set<Long> nodeIds;
/**
* 数据权限解析后的单位id
*/
private Set<Long> ouIds;
} }
public static void remove() { public static void remove() {