Commit 814c2db65c72ee7dfa1b056d2eaf383cb9e99c00
1 parent
4b95146c
初始化数据权限模块
Showing
8 changed files
with
437 additions
and
32 deletions
yudao-dependencies/pom.xml
| ... | ... | @@ -24,7 +24,7 @@ |
| 24 | 24 | <!-- DB 相关 --> |
| 25 | 25 | <mysql.version>5.1.46</mysql.version> |
| 26 | 26 | <druid.version>1.2.4</druid.version> |
| 27 | - <mybatis-plus.version>3.4.2</mybatis-plus.version> | |
| 27 | + <mybatis-plus.version>3.4.3.4</mybatis-plus.version> | |
| 28 | 28 | <dynamic-datasource.version>3.3.2</dynamic-datasource.version> |
| 29 | 29 | <redisson.version>3.16.3</redisson.version> |
| 30 | 30 | <!-- Config 配置中心相关 --> | ... | ... |
yudao-framework/pom.xml
| ... | ... | @@ -33,7 +33,7 @@ |
| 33 | 33 | <module>yudao-spring-boot-starter-biz-weixin</module> |
| 34 | 34 | <module>yudao-spring-boot-starter-extension</module> |
| 35 | 35 | <module>yudao-spring-boot-starter-tenant</module> |
| 36 | - <module>yudao-spring-boot-starter-datascope</module> | |
| 36 | + <module>yudao-spring-boot-starter-data-permission</module> | |
| 37 | 37 | </modules> |
| 38 | 38 | |
| 39 | 39 | <artifactId>yudao-framework</artifactId> | ... | ... |
yudao-framework/yudao-spring-boot-starter-datascope/pom.xml renamed to yudao-framework/yudao-spring-boot-starter-data-permission/pom.xml
| ... | ... | @@ -8,7 +8,7 @@ |
| 8 | 8 | <version>${revision}</version> |
| 9 | 9 | </parent> |
| 10 | 10 | <modelVersion>4.0.0</modelVersion> |
| 11 | - <artifactId>yudao-spring-boot-starter-datascope</artifactId> | |
| 11 | + <artifactId>yudao-spring-boot-starter-data-permission</artifactId> | |
| 12 | 12 | <packaging>jar</packaging> |
| 13 | 13 | |
| 14 | 14 | <name>${artifactId}</name> |
| ... | ... | @@ -21,40 +21,12 @@ |
| 21 | 21 | <artifactId>yudao-common</artifactId> |
| 22 | 22 | </dependency> |
| 23 | 23 | |
| 24 | - <!-- Web 相关 --> | |
| 25 | - <dependency> | |
| 26 | - <groupId>org.springframework.boot</groupId> | |
| 27 | - <artifactId>spring-boot-starter-web</artifactId> | |
| 28 | - </dependency> | |
| 29 | - | |
| 30 | - <dependency> | |
| 31 | - <groupId>cn.iocoder.boot</groupId> | |
| 32 | - <artifactId>yudao-spring-boot-starter-security</artifactId> | |
| 33 | - </dependency> | |
| 34 | - | |
| 35 | 24 | <!-- DB 相关 --> |
| 36 | 25 | <dependency> |
| 37 | 26 | <groupId>cn.iocoder.boot</groupId> |
| 38 | 27 | <artifactId>yudao-spring-boot-starter-mybatis</artifactId> |
| 39 | 28 | </dependency> |
| 40 | 29 | |
| 41 | - <dependency> | |
| 42 | - <groupId>cn.iocoder.boot</groupId> | |
| 43 | - <artifactId>yudao-spring-boot-starter-redis</artifactId> | |
| 44 | - </dependency> | |
| 45 | - | |
| 46 | - <!-- Job 定时任务相关 --> | |
| 47 | - <dependency> | |
| 48 | - <groupId>cn.iocoder.boot</groupId> | |
| 49 | - <artifactId>yudao-spring-boot-starter-job</artifactId> | |
| 50 | - </dependency> | |
| 51 | - | |
| 52 | - <!-- 消息队列相关 --> | |
| 53 | - <dependency> | |
| 54 | - <groupId>cn.iocoder.boot</groupId> | |
| 55 | - <artifactId>yudao-spring-boot-starter-mq</artifactId> | |
| 56 | - </dependency> | |
| 57 | - | |
| 58 | 30 | <!-- Test 测试相关 --> |
| 59 | 31 | <dependency> |
| 60 | 32 | <groupId>org.springframework.boot</groupId> | ... | ... |
yudao-framework/yudao-spring-boot-starter-data-permission/src/main/java/cn/iocoder/yudao/framework/datascope/core/interceptor/DataPermissionInterceptor.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.datascope.core.interceptor; | |
| 2 | + | |
| 3 | +import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper; | |
| 4 | +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; | |
| 5 | +import com.baomidou.mybatisplus.core.toolkit.PluginUtils; | |
| 6 | +import com.baomidou.mybatisplus.core.toolkit.StringPool; | |
| 7 | +import com.baomidou.mybatisplus.extension.parser.JsqlParserSupport; | |
| 8 | +import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor; | |
| 9 | +import net.sf.jsqlparser.expression.*; | |
| 10 | +import net.sf.jsqlparser.expression.operators.conditional.AndExpression; | |
| 11 | +import net.sf.jsqlparser.expression.operators.conditional.OrExpression; | |
| 12 | +import net.sf.jsqlparser.expression.operators.relational.*; | |
| 13 | +import net.sf.jsqlparser.schema.Column; | |
| 14 | +import net.sf.jsqlparser.schema.Table; | |
| 15 | +import net.sf.jsqlparser.statement.delete.Delete; | |
| 16 | +import net.sf.jsqlparser.statement.select.*; | |
| 17 | +import net.sf.jsqlparser.statement.update.Update; | |
| 18 | +import org.apache.ibatis.executor.Executor; | |
| 19 | +import org.apache.ibatis.executor.statement.StatementHandler; | |
| 20 | +import org.apache.ibatis.mapping.BoundSql; | |
| 21 | +import org.apache.ibatis.mapping.MappedStatement; | |
| 22 | +import org.apache.ibatis.mapping.SqlCommandType; | |
| 23 | +import org.apache.ibatis.session.ResultHandler; | |
| 24 | +import org.apache.ibatis.session.RowBounds; | |
| 25 | + | |
| 26 | +import java.sql.Connection; | |
| 27 | +import java.sql.SQLException; | |
| 28 | +import java.util.Collection; | |
| 29 | +import java.util.Deque; | |
| 30 | +import java.util.LinkedList; | |
| 31 | +import java.util.List; | |
| 32 | + | |
| 33 | +public class DataPermissionInterceptor extends JsqlParserSupport implements InnerInterceptor { | |
| 34 | + | |
| 35 | +// private TenantLineHandler tenantLineHandler; | |
| 36 | + | |
| 37 | + @Override | |
| 38 | + public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException { | |
| 39 | + if (InterceptorIgnoreHelper.willIgnoreTenantLine(ms.getId())) return; | |
| 40 | + PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql); | |
| 41 | + mpBs.sql(parserSingle(mpBs.sql(), null)); | |
| 42 | + } | |
| 43 | + | |
| 44 | + @Override | |
| 45 | + public void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) { | |
| 46 | + PluginUtils.MPStatementHandler mpSh = PluginUtils.mpStatementHandler(sh); | |
| 47 | + MappedStatement ms = mpSh.mappedStatement(); | |
| 48 | + SqlCommandType sct = ms.getSqlCommandType(); | |
| 49 | + if (sct == SqlCommandType.UPDATE || sct == SqlCommandType.DELETE) { // 无需处理 Insert 语句 | |
| 50 | + if (InterceptorIgnoreHelper.willIgnoreTenantLine(ms.getId())) return; | |
| 51 | + PluginUtils.MPBoundSql mpBs = mpSh.mPBoundSql(); | |
| 52 | + mpBs.sql(parserMulti(mpBs.sql(), null)); | |
| 53 | + } | |
| 54 | + } | |
| 55 | + | |
| 56 | + @Override | |
| 57 | + protected void processSelect(Select select, int index, String sql, Object obj) { | |
| 58 | + processSelectBody(select.getSelectBody()); | |
| 59 | + List<WithItem> withItemsList = select.getWithItemsList(); | |
| 60 | + if (!CollectionUtils.isEmpty(withItemsList)) { | |
| 61 | + withItemsList.forEach(this::processSelectBody); | |
| 62 | + } | |
| 63 | + } | |
| 64 | + | |
| 65 | + protected void processSelectBody(SelectBody selectBody) { | |
| 66 | + if (selectBody == null) { | |
| 67 | + return; | |
| 68 | + } | |
| 69 | + if (selectBody instanceof PlainSelect) { | |
| 70 | + processPlainSelect((PlainSelect) selectBody); | |
| 71 | + } else if (selectBody instanceof WithItem) { | |
| 72 | + WithItem withItem = (WithItem) selectBody; | |
| 73 | + processSelectBody(withItem.getSubSelect().getSelectBody()); | |
| 74 | + } else { | |
| 75 | + SetOperationList operationList = (SetOperationList) selectBody; | |
| 76 | + List<SelectBody> selectBodys = operationList.getSelects(); | |
| 77 | + if (CollectionUtils.isNotEmpty(selectBodys)) { | |
| 78 | + selectBodys.forEach(this::processSelectBody); | |
| 79 | + } | |
| 80 | + } | |
| 81 | + } | |
| 82 | + | |
| 83 | + /** | |
| 84 | + * update 语句处理 | |
| 85 | + */ | |
| 86 | + @Override | |
| 87 | + protected void processUpdate(Update update, int index, String sql, Object obj) { | |
| 88 | + final Table table = update.getTable(); | |
| 89 | + if (ignoreTable(table.getName())) { | |
| 90 | + // 过滤退出执行 | |
| 91 | + return; | |
| 92 | + } | |
| 93 | + update.setWhere(this.andExpression(table, update.getWhere())); | |
| 94 | + } | |
| 95 | + | |
| 96 | + /** | |
| 97 | + * delete 语句处理 | |
| 98 | + */ | |
| 99 | + @Override | |
| 100 | + protected void processDelete(Delete delete, int index, String sql, Object obj) { | |
| 101 | + if (ignoreTable(delete.getTable().getName())) { | |
| 102 | + // 过滤退出执行 | |
| 103 | + return; | |
| 104 | + } | |
| 105 | + delete.setWhere(this.andExpression(delete.getTable(), delete.getWhere())); | |
| 106 | + } | |
| 107 | + | |
| 108 | + /** | |
| 109 | + * delete update 语句 where 处理 | |
| 110 | + */ | |
| 111 | + protected BinaryExpression andExpression(Table table, Expression where) { | |
| 112 | + //获得where条件表达式 | |
| 113 | + EqualsTo equalsTo = new EqualsTo(); | |
| 114 | + equalsTo.setLeftExpression(this.getAliasColumn(table)); | |
| 115 | + equalsTo.setRightExpression(getTenantId()); | |
| 116 | + if (null != where) { | |
| 117 | + if (where instanceof OrExpression) { | |
| 118 | + return new AndExpression(equalsTo, new Parenthesis(where)); | |
| 119 | + } else { | |
| 120 | + return new AndExpression(equalsTo, where); | |
| 121 | + } | |
| 122 | + } | |
| 123 | + return equalsTo; | |
| 124 | + } | |
| 125 | + | |
| 126 | + /** | |
| 127 | + * 追加 SelectItem | |
| 128 | + * | |
| 129 | + * @param selectItems SelectItem | |
| 130 | + */ | |
| 131 | + protected void appendSelectItem(List<SelectItem> selectItems) { | |
| 132 | + if (CollectionUtils.isEmpty(selectItems)) return; | |
| 133 | + if (selectItems.size() == 1) { | |
| 134 | + SelectItem item = selectItems.get(0); | |
| 135 | + if (item instanceof AllColumns || item instanceof AllTableColumns) return; | |
| 136 | + } | |
| 137 | + selectItems.add(new SelectExpressionItem(new Column(getTenantIdColumn()))); | |
| 138 | + } | |
| 139 | + | |
| 140 | + /** | |
| 141 | + * 处理 PlainSelect | |
| 142 | + */ | |
| 143 | + protected void processPlainSelect(PlainSelect plainSelect) { | |
| 144 | + FromItem fromItem = plainSelect.getFromItem(); | |
| 145 | + Expression where = plainSelect.getWhere(); | |
| 146 | + processWhereSubSelect(where); | |
| 147 | + if (fromItem instanceof Table) { | |
| 148 | + Table fromTable = (Table) fromItem; | |
| 149 | + if (!ignoreTable(fromTable.getName())) { | |
| 150 | + //#1186 github | |
| 151 | + plainSelect.setWhere(builderExpression(where, fromTable)); | |
| 152 | + } | |
| 153 | + } else { | |
| 154 | + processFromItem(fromItem); | |
| 155 | + } | |
| 156 | + //#3087 github | |
| 157 | + List<SelectItem> selectItems = plainSelect.getSelectItems(); | |
| 158 | + if (CollectionUtils.isNotEmpty(selectItems)) { | |
| 159 | + selectItems.forEach(this::processSelectItem); | |
| 160 | + } | |
| 161 | + List<Join> joins = plainSelect.getJoins(); | |
| 162 | + if (CollectionUtils.isNotEmpty(joins)) { | |
| 163 | + processJoins(joins); | |
| 164 | + } | |
| 165 | + } | |
| 166 | + | |
| 167 | + /** | |
| 168 | + * 处理where条件内的子查询 | |
| 169 | + * <p> | |
| 170 | + * 支持如下: | |
| 171 | + * 1. in | |
| 172 | + * 2. = | |
| 173 | + * 3. > | |
| 174 | + * 4. < | |
| 175 | + * 5. >= | |
| 176 | + * 6. <= | |
| 177 | + * 7. <> | |
| 178 | + * 8. EXISTS | |
| 179 | + * 9. NOT EXISTS | |
| 180 | + * <p> | |
| 181 | + * 前提条件: | |
| 182 | + * 1. 子查询必须放在小括号中 | |
| 183 | + * 2. 子查询一般放在比较操作符的右边 | |
| 184 | + * | |
| 185 | + * @param where where 条件 | |
| 186 | + */ | |
| 187 | + protected void processWhereSubSelect(Expression where) { | |
| 188 | + if (where == null) { | |
| 189 | + return; | |
| 190 | + } | |
| 191 | + if (where instanceof FromItem) { | |
| 192 | + processFromItem((FromItem) where); | |
| 193 | + return; | |
| 194 | + } | |
| 195 | + if (where.toString().indexOf("SELECT") > 0) { | |
| 196 | + // 有子查询 | |
| 197 | + if (where instanceof BinaryExpression) { | |
| 198 | + // 比较符号 , and , or , 等等 | |
| 199 | + BinaryExpression expression = (BinaryExpression) where; | |
| 200 | + processWhereSubSelect(expression.getLeftExpression()); | |
| 201 | + processWhereSubSelect(expression.getRightExpression()); | |
| 202 | + } else if (where instanceof InExpression) { | |
| 203 | + // in | |
| 204 | + InExpression expression = (InExpression) where; | |
| 205 | + ItemsList itemsList = expression.getRightItemsList(); | |
| 206 | + if (itemsList instanceof SubSelect) { | |
| 207 | + processSelectBody(((SubSelect) itemsList).getSelectBody()); | |
| 208 | + } | |
| 209 | + } else if (where instanceof ExistsExpression) { | |
| 210 | + // exists | |
| 211 | + ExistsExpression expression = (ExistsExpression) where; | |
| 212 | + processWhereSubSelect(expression.getRightExpression()); | |
| 213 | + } else if (where instanceof NotExpression) { | |
| 214 | + // not exists | |
| 215 | + NotExpression expression = (NotExpression) where; | |
| 216 | + processWhereSubSelect(expression.getExpression()); | |
| 217 | + } else if (where instanceof Parenthesis) { | |
| 218 | + Parenthesis expression = (Parenthesis) where; | |
| 219 | + processWhereSubSelect(expression.getExpression()); | |
| 220 | + } | |
| 221 | + } | |
| 222 | + } | |
| 223 | + | |
| 224 | + protected void processSelectItem(SelectItem selectItem) { | |
| 225 | + if (selectItem instanceof SelectExpressionItem) { | |
| 226 | + SelectExpressionItem selectExpressionItem = (SelectExpressionItem) selectItem; | |
| 227 | + if (selectExpressionItem.getExpression() instanceof SubSelect) { | |
| 228 | + processSelectBody(((SubSelect) selectExpressionItem.getExpression()).getSelectBody()); | |
| 229 | + } else if (selectExpressionItem.getExpression() instanceof Function) { | |
| 230 | + processFunction((Function) selectExpressionItem.getExpression()); | |
| 231 | + } | |
| 232 | + } | |
| 233 | + } | |
| 234 | + | |
| 235 | + /** | |
| 236 | + * 处理函数 | |
| 237 | + * <p>支持: 1. select fun(args..) 2. select fun1(fun2(args..),args..)<p> | |
| 238 | + * <p> fixed gitee pulls/141</p> | |
| 239 | + * | |
| 240 | + * @param function | |
| 241 | + */ | |
| 242 | + protected void processFunction(Function function) { | |
| 243 | + ExpressionList parameters = function.getParameters(); | |
| 244 | + if (parameters != null) { | |
| 245 | + parameters.getExpressions().forEach(expression -> { | |
| 246 | + if (expression instanceof SubSelect) { | |
| 247 | + processSelectBody(((SubSelect) expression).getSelectBody()); | |
| 248 | + } else if (expression instanceof Function) { | |
| 249 | + processFunction((Function) expression); | |
| 250 | + } | |
| 251 | + }); | |
| 252 | + } | |
| 253 | + } | |
| 254 | + | |
| 255 | + /** | |
| 256 | + * 处理子查询等 | |
| 257 | + */ | |
| 258 | + protected void processFromItem(FromItem fromItem) { | |
| 259 | + if (fromItem instanceof SubJoin) { | |
| 260 | + SubJoin subJoin = (SubJoin) fromItem; | |
| 261 | + if (subJoin.getJoinList() != null) { | |
| 262 | + processJoins(subJoin.getJoinList()); | |
| 263 | + } | |
| 264 | + if (subJoin.getLeft() != null) { | |
| 265 | + processFromItem(subJoin.getLeft()); | |
| 266 | + } | |
| 267 | + } else if (fromItem instanceof SubSelect) { | |
| 268 | + SubSelect subSelect = (SubSelect) fromItem; | |
| 269 | + if (subSelect.getSelectBody() != null) { | |
| 270 | + processSelectBody(subSelect.getSelectBody()); | |
| 271 | + } | |
| 272 | + } else if (fromItem instanceof ValuesList) { | |
| 273 | + logger.debug("Perform a subquery, if you do not give us feedback"); | |
| 274 | + } else if (fromItem instanceof LateralSubSelect) { | |
| 275 | + LateralSubSelect lateralSubSelect = (LateralSubSelect) fromItem; | |
| 276 | + if (lateralSubSelect.getSubSelect() != null) { | |
| 277 | + SubSelect subSelect = lateralSubSelect.getSubSelect(); | |
| 278 | + if (subSelect.getSelectBody() != null) { | |
| 279 | + processSelectBody(subSelect.getSelectBody()); | |
| 280 | + } | |
| 281 | + } | |
| 282 | + } | |
| 283 | + } | |
| 284 | + | |
| 285 | + /** | |
| 286 | + * 处理 joins | |
| 287 | + * | |
| 288 | + * @param joins join 集合 | |
| 289 | + */ | |
| 290 | + private void processJoins(List<Join> joins) { | |
| 291 | + //对于 on 表达式写在最后的 join,需要记录下前面多个 on 的表名 | |
| 292 | + Deque<Table> tables = new LinkedList<>(); | |
| 293 | + for (Join join : joins) { | |
| 294 | + // 处理 on 表达式 | |
| 295 | + FromItem fromItem = join.getRightItem(); | |
| 296 | + if (fromItem instanceof Table) { | |
| 297 | + Table fromTable = (Table) fromItem; | |
| 298 | + // 获取 join 尾缀的 on 表达式列表 | |
| 299 | + Collection<Expression> originOnExpressions = join.getOnExpressions(); | |
| 300 | + // 正常 join on 表达式只有一个,立刻处理 | |
| 301 | + if (originOnExpressions.size() == 1) { | |
| 302 | + processJoin(join); | |
| 303 | + continue; | |
| 304 | + } | |
| 305 | + // 当前表是否忽略 | |
| 306 | + boolean needIgnore = ignoreTable(fromTable.getName()); | |
| 307 | + // 表名压栈,忽略的表压入 null,以便后续不处理 | |
| 308 | + tables.push(needIgnore ? null : fromTable); | |
| 309 | + // 尾缀多个 on 表达式的时候统一处理 | |
| 310 | + if (originOnExpressions.size() > 1) { | |
| 311 | + Collection<Expression> onExpressions = new LinkedList<>(); | |
| 312 | + for (Expression originOnExpression : originOnExpressions) { | |
| 313 | + Table currentTable = tables.poll(); | |
| 314 | + if (currentTable == null) { | |
| 315 | + onExpressions.add(originOnExpression); | |
| 316 | + } else { | |
| 317 | + onExpressions.add(builderExpression(originOnExpression, currentTable)); | |
| 318 | + } | |
| 319 | + } | |
| 320 | + join.setOnExpressions(onExpressions); | |
| 321 | + } | |
| 322 | + } else { | |
| 323 | + // 处理右边连接的子表达式 | |
| 324 | + processFromItem(fromItem); | |
| 325 | + } | |
| 326 | + } | |
| 327 | + } | |
| 328 | + | |
| 329 | + /** | |
| 330 | + * 处理联接语句 | |
| 331 | + */ | |
| 332 | + protected void processJoin(Join join) { | |
| 333 | + if (join.getRightItem() instanceof Table) { | |
| 334 | + Table fromTable = (Table) join.getRightItem(); | |
| 335 | + if (ignoreTable(fromTable.getName())) { | |
| 336 | + // 过滤退出执行 | |
| 337 | + return; | |
| 338 | + } | |
| 339 | + // 走到这里说明 on 表达式肯定只有一个 | |
| 340 | + Collection<Expression> originOnExpressions = join.getOnExpressions(); | |
| 341 | + List<Expression> onExpressions = new LinkedList<>(); | |
| 342 | + onExpressions.add(builderExpression(originOnExpressions.iterator().next(), fromTable)); | |
| 343 | + join.setOnExpressions(onExpressions); | |
| 344 | + } | |
| 345 | + } | |
| 346 | + | |
| 347 | + /** | |
| 348 | + * 处理条件 | |
| 349 | + */ | |
| 350 | + protected Expression builderExpression(Expression currentExpression, Table table) { | |
| 351 | + EqualsTo equalsTo = new EqualsTo(); | |
| 352 | + equalsTo.setLeftExpression(this.getAliasColumn(table)); | |
| 353 | + equalsTo.setRightExpression(getTenantId()); | |
| 354 | + if (currentExpression == null) { | |
| 355 | + return equalsTo; | |
| 356 | + } | |
| 357 | + if (currentExpression instanceof OrExpression) { | |
| 358 | + return new AndExpression(new Parenthesis(currentExpression), equalsTo); | |
| 359 | + } else { | |
| 360 | + return new AndExpression(currentExpression, equalsTo); | |
| 361 | + } | |
| 362 | + } | |
| 363 | + | |
| 364 | + /** | |
| 365 | + * 租户字段别名设置 | |
| 366 | + * <p>tenantId 或 tableAlias.tenantId</p> | |
| 367 | + * | |
| 368 | + * @param table 表对象 | |
| 369 | + * @return 字段 | |
| 370 | + */ | |
| 371 | + protected Column getAliasColumn(Table table) { | |
| 372 | + StringBuilder column = new StringBuilder(); | |
| 373 | + if (table.getAlias() != null) { | |
| 374 | + column.append(table.getAlias().getName()).append(StringPool.DOT); | |
| 375 | + } | |
| 376 | + column.append(getTenantIdColumn()); | |
| 377 | + return new Column(column.toString()); | |
| 378 | + } | |
| 379 | + | |
| 380 | +// @Override | |
| 381 | +// public void setProperties(Properties properties) { | |
| 382 | +// PropertyMapper.newInstance(properties).whenNotBlank("tenantLineHandler", | |
| 383 | +// ClassUtils::newInstance, this::setTenantLineHandler); | |
| 384 | +// } | |
| 385 | + | |
| 386 | + // TODO 芋艿:未实现 | |
| 387 | + | |
| 388 | + private boolean ignoreTable(String tableName) { | |
| 389 | + return false; | |
| 390 | + } | |
| 391 | + | |
| 392 | + private String getTenantIdColumn() { | |
| 393 | + return "dept_id"; | |
| 394 | + } | |
| 395 | + | |
| 396 | + private Expression getTenantId() { | |
| 397 | + return new LongValue(1L); | |
| 398 | + } | |
| 399 | + | |
| 400 | +} | ... | ... |
yudao-framework/yudao-spring-boot-starter-data-permission/src/main/java/cn/iocoder/yudao/framework/datascope/core/package-info.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.datascope.core; | ... | ... |
yudao-framework/yudao-spring-boot-starter-datascope/src/main/java/cn/iocoder/yudao/framework/datascope/package-info.java renamed to yudao-framework/yudao-spring-boot-starter-data-permission/src/main/java/cn/iocoder/yudao/framework/datascope/package-info.java
yudao-framework/yudao-spring-boot-starter-data-permission/src/test/java/cn/iocoder/yudao/framework/datascope/core/interceptor/DataPermissionInterceptorTest.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.datascope.core.interceptor; | |
| 2 | + | |
| 3 | +import org.junit.jupiter.api.Test; | |
| 4 | + | |
| 5 | +import static org.assertj.core.api.Assertions.assertThat; | |
| 6 | + | |
| 7 | +public class DataPermissionInterceptorTest { | |
| 8 | + | |
| 9 | + private final DataPermissionInterceptor interceptor = new DataPermissionInterceptor(); | |
| 10 | + | |
| 11 | + @Test | |
| 12 | + void selectSingle() { | |
| 13 | + // 单表 | |
| 14 | + assertSql("select * from entity where id = ?", | |
| 15 | + "SELECT * FROM entity WHERE id = ? AND tenant_id = 1"); | |
| 16 | + | |
| 17 | + assertSql("select * from entity where id = ? or name = ?", | |
| 18 | + "SELECT * FROM entity WHERE (id = ? OR name = ?) AND tenant_id = 1"); | |
| 19 | + | |
| 20 | + assertSql("SELECT * FROM entity WHERE (id = ? OR name = ?)", | |
| 21 | + "SELECT * FROM entity WHERE (id = ? OR name = ?) AND tenant_id = 1"); | |
| 22 | + | |
| 23 | + /* not */ | |
| 24 | + assertSql("SELECT * FROM entity WHERE not (id = ? OR name = ?)", | |
| 25 | + "SELECT * FROM entity WHERE NOT (id = ? OR name = ?) AND tenant_id = 1"); | |
| 26 | + } | |
| 27 | + | |
| 28 | + private void assertSql(String sql, String targetSql) { | |
| 29 | + assertThat(interceptor.parserSingle(sql, null)).isEqualTo(targetSql); | |
| 30 | + } | |
| 31 | + | |
| 32 | +} | ... | ... |
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
| ... | ... | @@ -33,7 +33,7 @@ public interface BaseMapperX<T> extends BaseMapper<T> { |
| 33 | 33 | } |
| 34 | 34 | |
| 35 | 35 | default Integer selectCount(String field, Object value) { |
| 36 | - return selectCount(new QueryWrapper<T>().eq(field, value)); | |
| 36 | + return selectCount(new QueryWrapper<T>().eq(field, value)).intValue(); | |
| 37 | 37 | } |
| 38 | 38 | |
| 39 | 39 | default List<T> selectList() { | ... | ... |