Commit 814c2db65c72ee7dfa1b056d2eaf383cb9e99c00
1 parent
4b95146c
初始化数据权限模块
Showing
8 changed files
with
437 additions
and
32 deletions
yudao-dependencies/pom.xml
| @@ -24,7 +24,7 @@ | @@ -24,7 +24,7 @@ | ||
| 24 | <!-- DB 相关 --> | 24 | <!-- DB 相关 --> |
| 25 | <mysql.version>5.1.46</mysql.version> | 25 | <mysql.version>5.1.46</mysql.version> |
| 26 | <druid.version>1.2.4</druid.version> | 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 | <dynamic-datasource.version>3.3.2</dynamic-datasource.version> | 28 | <dynamic-datasource.version>3.3.2</dynamic-datasource.version> |
| 29 | <redisson.version>3.16.3</redisson.version> | 29 | <redisson.version>3.16.3</redisson.version> |
| 30 | <!-- Config 配置中心相关 --> | 30 | <!-- Config 配置中心相关 --> |
yudao-framework/pom.xml
| @@ -33,7 +33,7 @@ | @@ -33,7 +33,7 @@ | ||
| 33 | <module>yudao-spring-boot-starter-biz-weixin</module> | 33 | <module>yudao-spring-boot-starter-biz-weixin</module> |
| 34 | <module>yudao-spring-boot-starter-extension</module> | 34 | <module>yudao-spring-boot-starter-extension</module> |
| 35 | <module>yudao-spring-boot-starter-tenant</module> | 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 | </modules> | 37 | </modules> |
| 38 | 38 | ||
| 39 | <artifactId>yudao-framework</artifactId> | 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,7 +8,7 @@ | ||
| 8 | <version>${revision}</version> | 8 | <version>${revision}</version> |
| 9 | </parent> | 9 | </parent> |
| 10 | <modelVersion>4.0.0</modelVersion> | 10 | <modelVersion>4.0.0</modelVersion> |
| 11 | - <artifactId>yudao-spring-boot-starter-datascope</artifactId> | 11 | + <artifactId>yudao-spring-boot-starter-data-permission</artifactId> |
| 12 | <packaging>jar</packaging> | 12 | <packaging>jar</packaging> |
| 13 | 13 | ||
| 14 | <name>${artifactId}</name> | 14 | <name>${artifactId}</name> |
| @@ -21,40 +21,12 @@ | @@ -21,40 +21,12 @@ | ||
| 21 | <artifactId>yudao-common</artifactId> | 21 | <artifactId>yudao-common</artifactId> |
| 22 | </dependency> | 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 | <!-- DB 相关 --> | 24 | <!-- DB 相关 --> |
| 36 | <dependency> | 25 | <dependency> |
| 37 | <groupId>cn.iocoder.boot</groupId> | 26 | <groupId>cn.iocoder.boot</groupId> |
| 38 | <artifactId>yudao-spring-boot-starter-mybatis</artifactId> | 27 | <artifactId>yudao-spring-boot-starter-mybatis</artifactId> |
| 39 | </dependency> | 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 | <!-- Test 测试相关 --> | 30 | <!-- Test 测试相关 --> |
| 59 | <dependency> | 31 | <dependency> |
| 60 | <groupId>org.springframework.boot</groupId> | 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,7 +33,7 @@ public interface BaseMapperX<T> extends BaseMapper<T> { | ||
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | default Integer selectCount(String field, Object value) { | 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 | default List<T> selectList() { | 39 | default List<T> selectList() { |