mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 10:18:42 +08:00 
			
		
		
		
	【依赖】mybatis-plus from 3.5.5 to 3.5.7
This commit is contained in:
		| @@ -23,10 +23,11 @@ | ||||
|         <knife4j.version>4.3.0</knife4j.version> | ||||
|         <!-- DB 相关 --> | ||||
|         <druid.version>1.2.23</druid.version> | ||||
|         <mybatis-plus.version>3.5.5</mybatis-plus.version> | ||||
|         <mybatis-plus-generator.version>3.5.5</mybatis-plus-generator.version> | ||||
|         <mybatis.version>3.5.16</mybatis.version> | ||||
|         <mybatis-plus.version>3.5.7</mybatis-plus.version> | ||||
|         <mybatis-plus-generator.version>3.5.7</mybatis-plus-generator.version> | ||||
|         <dynamic-datasource.version>4.3.1</dynamic-datasource.version> | ||||
|         <mybatis-plus-join.version>1.4.10</mybatis-plus-join.version> | ||||
|         <mybatis-plus-join.version>1.4.13</mybatis-plus-join.version> | ||||
|         <easy-trans.version>2.2.11</easy-trans.version> | ||||
|         <redisson.version>3.26.0</redisson.version> | ||||
|         <dm8.jdbc.version>8.1.3.62</dm8.jdbc.version> | ||||
| @@ -171,6 +172,11 @@ | ||||
|                 <artifactId>druid-spring-boot-3-starter</artifactId> | ||||
|                 <version>${druid.version}</version> | ||||
|             </dependency> | ||||
|             <dependency> | ||||
|                 <groupId>org.mybatis</groupId> | ||||
|                 <artifactId>mybatis</artifactId> | ||||
|                 <version>${mybatis.version}</version> | ||||
|             </dependency> | ||||
|             <dependency> | ||||
|                 <groupId>com.baomidou</groupId> | ||||
|                 <artifactId>mybatis-plus-spring-boot3-starter</artifactId> | ||||
|   | ||||
| @@ -7,19 +7,17 @@ import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRuleFac | ||||
| import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; | ||||
| import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; | ||||
| import com.baomidou.mybatisplus.core.toolkit.PluginUtils; | ||||
| import com.baomidou.mybatisplus.extension.parser.JsqlParserSupport; | ||||
| import com.baomidou.mybatisplus.extension.plugins.inner.BaseMultiTableInnerInterceptor; | ||||
| import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor; | ||||
| import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor; | ||||
| import lombok.Getter; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import net.sf.jsqlparser.expression.*; | ||||
| import net.sf.jsqlparser.expression.Expression; | ||||
| import net.sf.jsqlparser.expression.operators.conditional.AndExpression; | ||||
| import net.sf.jsqlparser.expression.operators.conditional.OrExpression; | ||||
| import net.sf.jsqlparser.expression.operators.relational.ExistsExpression; | ||||
| import net.sf.jsqlparser.expression.operators.relational.ExpressionList; | ||||
| import net.sf.jsqlparser.expression.operators.relational.InExpression; | ||||
| import net.sf.jsqlparser.schema.Table; | ||||
| import net.sf.jsqlparser.statement.delete.Delete; | ||||
| import net.sf.jsqlparser.statement.select.*; | ||||
| import net.sf.jsqlparser.statement.select.Select; | ||||
| import net.sf.jsqlparser.statement.select.WithItem; | ||||
| import net.sf.jsqlparser.statement.update.Update; | ||||
| import org.apache.ibatis.executor.Executor; | ||||
| import org.apache.ibatis.executor.statement.StatementHandler; | ||||
| @@ -30,20 +28,25 @@ import org.apache.ibatis.session.ResultHandler; | ||||
| import org.apache.ibatis.session.RowBounds; | ||||
|  | ||||
| import java.sql.Connection; | ||||
| import java.util.*; | ||||
| import java.util.Collections; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Set; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
|  | ||||
| /** | ||||
|  * 数据权限拦截器,通过 {@link DataPermissionRule} 数据权限规则,重写 SQL 的方式来实现 | ||||
|  * 主要的 SQL 重写方法,可见 {@link #builderExpression(Expression, List)} 方法 | ||||
|  * 主要的 SQL 重写方法,可见 {@link #buildTableExpression(Table, Expression, String)} 方法 | ||||
|  * | ||||
|  * 整体的代码实现上,参考 {@link com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor} 实现。 | ||||
|  * 所以每次 MyBatis Plus 升级时,需要 Review 下其具体的实现是否有变更! | ||||
|  * | ||||
|  * 为什么不直接基于 {@link DataPermissionInterceptor} 实现?因为它是 MyBatis Plus 3.5.2 版本才出来,当时 yudao 已经实现数据权限了! | ||||
|  * | ||||
|  * @author 芋道源码 | ||||
|  */ | ||||
| @RequiredArgsConstructor | ||||
| public class DataPermissionDatabaseInterceptor extends JsqlParserSupport implements InnerInterceptor { | ||||
| public class DataPermissionDatabaseInterceptor extends BaseMultiTableInnerInterceptor implements InnerInterceptor { | ||||
|  | ||||
|     private final DataPermissionRuleFactory ruleFactory; | ||||
|  | ||||
| @@ -101,10 +104,11 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme | ||||
|  | ||||
|     @Override | ||||
|     protected void processSelect(Select select, int index, String sql, Object obj) { | ||||
|         processSelectBody(select.getSelectBody()); | ||||
|         final String whereSegment = (String) obj; | ||||
|         processSelectBody(select, whereSegment); | ||||
|         List<WithItem> withItemsList = select.getWithItemsList(); | ||||
|         if (!CollectionUtils.isEmpty(withItemsList)) { | ||||
|             withItemsList.forEach(this::processSelectBody); | ||||
|             withItemsList.forEach(withItem -> processSelectBody(withItem, whereSegment)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -113,8 +117,10 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme | ||||
|      */ | ||||
|     @Override | ||||
|     protected void processUpdate(Update update, int index, String sql, Object obj) { | ||||
|         final Table table = update.getTable(); | ||||
|         update.setWhere(this.builderExpression(update.getWhere(), table)); | ||||
|         final Expression sqlSegment = getUpdateOrDeleteExpression(update.getTable(), update.getWhere(), (String) obj); | ||||
|         if (null != sqlSegment) { | ||||
|             update.setWhere(sqlSegment); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -122,367 +128,16 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme | ||||
|      */ | ||||
|     @Override | ||||
|     protected void processDelete(Delete delete, int index, String sql, Object obj) { | ||||
|         delete.setWhere(this.builderExpression(delete.getWhere(), delete.getTable())); | ||||
|         final Expression sqlSegment = getUpdateOrDeleteExpression(delete.getTable(), delete.getWhere(), (String) obj); | ||||
|         if (null != sqlSegment) { | ||||
|             delete.setWhere(sqlSegment); | ||||
|         } | ||||
|  | ||||
|     // ========== 和 TenantLineInnerInterceptor 一致的逻辑 ========== | ||||
|  | ||||
|     protected void processSelectBody(SelectBody selectBody) { | ||||
|         if (selectBody == null) { | ||||
|             return; | ||||
|         } | ||||
|         if (selectBody instanceof PlainSelect) { | ||||
|             processPlainSelect((PlainSelect) selectBody); | ||||
|         } else if (selectBody instanceof WithItem) { | ||||
|             WithItem withItem = (WithItem) selectBody; | ||||
|             processSelectBody(withItem.getSubSelect().getSelectBody()); | ||||
|         } else { | ||||
|             SetOperationList operationList = (SetOperationList) selectBody; | ||||
|             List<SelectBody> selectBodyList = operationList.getSelects(); | ||||
|             if (CollectionUtils.isNotEmpty(selectBodyList)) { | ||||
|                 selectBodyList.forEach(this::processSelectBody); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 处理 PlainSelect | ||||
|      */ | ||||
|     protected void processPlainSelect(PlainSelect plainSelect) { | ||||
|         //#3087 github | ||||
|         List<SelectItem> selectItems = plainSelect.getSelectItems(); | ||||
|         if (CollectionUtils.isNotEmpty(selectItems)) { | ||||
|             selectItems.forEach(this::processSelectItem); | ||||
|         } | ||||
|  | ||||
|         // 处理 where 中的子查询 | ||||
|         Expression where = plainSelect.getWhere(); | ||||
|         processWhereSubSelect(where); | ||||
|  | ||||
|         // 处理 fromItem | ||||
|         FromItem fromItem = plainSelect.getFromItem(); | ||||
|         List<Table> list = processFromItem(fromItem); | ||||
|         List<Table> mainTables = new ArrayList<>(list); | ||||
|  | ||||
|         // 处理 join | ||||
|         List<Join> joins = plainSelect.getJoins(); | ||||
|         if (CollectionUtils.isNotEmpty(joins)) { | ||||
|             mainTables = processJoins(mainTables, joins); | ||||
|         } | ||||
|  | ||||
|         // 当有 mainTable 时,进行 where 条件追加 | ||||
|         if (CollectionUtils.isNotEmpty(mainTables)) { | ||||
|             plainSelect.setWhere(builderExpression(where, mainTables)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private List<Table> processFromItem(FromItem fromItem) { | ||||
|         // 处理括号括起来的表达式 | ||||
|         while (fromItem instanceof ParenthesisFromItem) { | ||||
|             fromItem = ((ParenthesisFromItem) fromItem).getFromItem(); | ||||
|         } | ||||
|  | ||||
|         List<Table> mainTables = new ArrayList<>(); | ||||
|         // 无 join 时的处理逻辑 | ||||
|         if (fromItem instanceof Table) { | ||||
|             Table fromTable = (Table) fromItem; | ||||
|             mainTables.add(fromTable); | ||||
|         } else if (fromItem instanceof SubJoin) { | ||||
|             // SubJoin 类型则还需要添加上 where 条件 | ||||
|             List<Table> tables = processSubJoin((SubJoin) fromItem); | ||||
|             mainTables.addAll(tables); | ||||
|         } else { | ||||
|             // 处理下 fromItem | ||||
|             processOtherFromItem(fromItem); | ||||
|         } | ||||
|         return mainTables; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 处理where条件内的子查询 | ||||
|      * <p> | ||||
|      * 支持如下: | ||||
|      * 1. in | ||||
|      * 2. = | ||||
|      * 3. > | ||||
|      * 4. < | ||||
|      * 5. >= | ||||
|      * 6. <= | ||||
|      * 7. <> | ||||
|      * 8. EXISTS | ||||
|      * 9. NOT EXISTS | ||||
|      * <p> | ||||
|      * 前提条件: | ||||
|      * 1. 子查询必须放在小括号中 | ||||
|      * 2. 子查询一般放在比较操作符的右边 | ||||
|      * | ||||
|      * @param where where 条件 | ||||
|      */ | ||||
|     protected void processWhereSubSelect(Expression where) { | ||||
|         if (where == null) { | ||||
|             return; | ||||
|         } | ||||
|         if (where instanceof FromItem) { | ||||
|             processOtherFromItem((FromItem) where); | ||||
|             return; | ||||
|         } | ||||
|         if (where.toString().indexOf("SELECT") > 0) { | ||||
|             // 有子查询 | ||||
|             if (where instanceof BinaryExpression) { | ||||
|                 // 比较符号 , and , or , 等等 | ||||
|                 BinaryExpression expression = (BinaryExpression) where; | ||||
|                 processWhereSubSelect(expression.getLeftExpression()); | ||||
|                 processWhereSubSelect(expression.getRightExpression()); | ||||
|             } else if (where instanceof InExpression) { | ||||
|                 // in | ||||
|                 InExpression expression = (InExpression) where; | ||||
|                 Expression inExpression = expression.getRightExpression(); | ||||
|                 if (inExpression instanceof SubSelect) { | ||||
|                     processSelectBody(((SubSelect) inExpression).getSelectBody()); | ||||
|                 } | ||||
|             } else if (where instanceof ExistsExpression) { | ||||
|                 // exists | ||||
|                 ExistsExpression expression = (ExistsExpression) where; | ||||
|                 processWhereSubSelect(expression.getRightExpression()); | ||||
|             } else if (where instanceof NotExpression) { | ||||
|                 // not exists | ||||
|                 NotExpression expression = (NotExpression) where; | ||||
|                 processWhereSubSelect(expression.getExpression()); | ||||
|             } else if (where instanceof Parenthesis) { | ||||
|                 Parenthesis expression = (Parenthesis) where; | ||||
|                 processWhereSubSelect(expression.getExpression()); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     protected void processSelectItem(SelectItem selectItem) { | ||||
|         if (selectItem instanceof SelectExpressionItem) { | ||||
|             SelectExpressionItem selectExpressionItem = (SelectExpressionItem) selectItem; | ||||
|             if (selectExpressionItem.getExpression() instanceof SubSelect) { | ||||
|                 processSelectBody(((SubSelect) selectExpressionItem.getExpression()).getSelectBody()); | ||||
|             } else if (selectExpressionItem.getExpression() instanceof Function) { | ||||
|                 processFunction((Function) selectExpressionItem.getExpression()); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 处理函数 | ||||
|      * <p>支持: 1. select fun(args..) 2. select fun1(fun2(args..),args..)<p> | ||||
|      * <p> fixed gitee pulls/141</p> | ||||
|      * | ||||
|      * @param function | ||||
|      */ | ||||
|     protected void processFunction(Function function) { | ||||
|         ExpressionList parameters = function.getParameters(); | ||||
|         if (parameters != null) { | ||||
|             parameters.getExpressions().forEach(expression -> { | ||||
|                 if (expression instanceof SubSelect) { | ||||
|                     processSelectBody(((SubSelect) expression).getSelectBody()); | ||||
|                 } else if (expression instanceof Function) { | ||||
|                     processFunction((Function) expression); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 处理子查询等 | ||||
|      */ | ||||
|     protected void processOtherFromItem(FromItem fromItem) { | ||||
|         // 去除括号 | ||||
|         while (fromItem instanceof ParenthesisFromItem) { | ||||
|             fromItem = ((ParenthesisFromItem) fromItem).getFromItem(); | ||||
|         } | ||||
|  | ||||
|         if (fromItem instanceof SubSelect) { | ||||
|             SubSelect subSelect = (SubSelect) fromItem; | ||||
|             if (subSelect.getSelectBody() != null) { | ||||
|                 processSelectBody(subSelect.getSelectBody()); | ||||
|             } | ||||
|         } else if (fromItem instanceof ValuesList) { | ||||
|             logger.debug("Perform a subQuery, if you do not give us feedback"); | ||||
|         } else if (fromItem instanceof LateralSubSelect) { | ||||
|             LateralSubSelect lateralSubSelect = (LateralSubSelect) fromItem; | ||||
|             if (lateralSubSelect.getSubSelect() != null) { | ||||
|                 SubSelect subSelect = lateralSubSelect.getSubSelect(); | ||||
|                 if (subSelect.getSelectBody() != null) { | ||||
|                     processSelectBody(subSelect.getSelectBody()); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 处理 sub join | ||||
|      * | ||||
|      * @param subJoin subJoin | ||||
|      * @return Table subJoin 中的主表 | ||||
|      */ | ||||
|     private List<Table> processSubJoin(SubJoin subJoin) { | ||||
|         List<Table> mainTables = new ArrayList<>(); | ||||
|         if (subJoin.getJoinList() != null) { | ||||
|             List<Table> list = processFromItem(subJoin.getLeft()); | ||||
|             mainTables.addAll(list); | ||||
|             mainTables = processJoins(mainTables, subJoin.getJoinList()); | ||||
|         } | ||||
|         return mainTables; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 处理 joins | ||||
|      * | ||||
|      * @param mainTables 可以为 null | ||||
|      * @param joins      join 集合 | ||||
|      * @return List<Table> 右连接查询的 Table 列表 | ||||
|      */ | ||||
|     private List<Table> processJoins(List<Table> mainTables, List<Join> joins) { | ||||
|         // join 表达式中最终的主表 | ||||
|         Table mainTable = null; | ||||
|         // 当前 join 的左表 | ||||
|         Table leftTable = null; | ||||
|  | ||||
|         if (mainTables == null) { | ||||
|             mainTables = new ArrayList<>(); | ||||
|         } else if (mainTables.size() == 1) { | ||||
|             mainTable = mainTables.get(0); | ||||
|             leftTable = mainTable; | ||||
|         } | ||||
|  | ||||
|         //对于 on 表达式写在最后的 join,需要记录下前面多个 on 的表名 | ||||
|         Deque<List<Table>> onTableDeque = new LinkedList<>(); | ||||
|         for (Join join : joins) { | ||||
|             // 处理 on 表达式 | ||||
|             FromItem joinItem = join.getRightItem(); | ||||
|  | ||||
|             // 获取当前 join 的表,subJoint 可以看作是一张表 | ||||
|             List<Table> joinTables = null; | ||||
|             if (joinItem instanceof Table) { | ||||
|                 joinTables = new ArrayList<>(); | ||||
|                 joinTables.add((Table) joinItem); | ||||
|             } else if (joinItem instanceof SubJoin) { | ||||
|                 joinTables = processSubJoin((SubJoin) joinItem); | ||||
|             } | ||||
|  | ||||
|             if (joinTables != null) { | ||||
|  | ||||
|                 // 如果是隐式内连接 | ||||
|                 if (join.isSimple()) { | ||||
|                     mainTables.addAll(joinTables); | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 // 当前表是否忽略 | ||||
|                 Table joinTable = joinTables.get(0); | ||||
|  | ||||
|                 List<Table> onTables = null; | ||||
|                 // 如果不要忽略,且是右连接,则记录下当前表 | ||||
|                 if (join.isRight()) { | ||||
|                     mainTable = joinTable; | ||||
|                     if (leftTable != null) { | ||||
|                         onTables = Collections.singletonList(leftTable); | ||||
|                     } | ||||
|                 } else if (join.isLeft()) { | ||||
|                     onTables = Collections.singletonList(joinTable); | ||||
|                 } else if (join.isInner()) { | ||||
|                     if (mainTable == null) { | ||||
|                         onTables = Collections.singletonList(joinTable); | ||||
|                     } else { | ||||
|                         onTables = Arrays.asList(mainTable, joinTable); | ||||
|                     } | ||||
|                     mainTable = null; | ||||
|                 } | ||||
|  | ||||
|                 mainTables = new ArrayList<>(); | ||||
|                 if (mainTable != null) { | ||||
|                     mainTables.add(mainTable); | ||||
|                 } | ||||
|  | ||||
|                 // 获取 join 尾缀的 on 表达式列表 | ||||
|                 Collection<Expression> originOnExpressions = join.getOnExpressions(); | ||||
|                 // 正常 join on 表达式只有一个,立刻处理 | ||||
|                 if (originOnExpressions.size() == 1 && onTables != null) { | ||||
|                     List<Expression> onExpressions = new LinkedList<>(); | ||||
|                     onExpressions.add(builderExpression(originOnExpressions.iterator().next(), onTables)); | ||||
|                     join.setOnExpressions(onExpressions); | ||||
|                     leftTable = joinTable; | ||||
|                     continue; | ||||
|                 } | ||||
|                 // 表名压栈,忽略的表压入 null,以便后续不处理 | ||||
|                 onTableDeque.push(onTables); | ||||
|                 // 尾缀多个 on 表达式的时候统一处理 | ||||
|                 if (originOnExpressions.size() > 1) { | ||||
|                     Collection<Expression> onExpressions = new LinkedList<>(); | ||||
|                     for (Expression originOnExpression : originOnExpressions) { | ||||
|                         List<Table> currentTableList = onTableDeque.poll(); | ||||
|                         if (CollectionUtils.isEmpty(currentTableList)) { | ||||
|                             onExpressions.add(originOnExpression); | ||||
|                         } else { | ||||
|                             onExpressions.add(builderExpression(originOnExpression, currentTableList)); | ||||
|                         } | ||||
|                     } | ||||
|                     join.setOnExpressions(onExpressions); | ||||
|                 } | ||||
|                 leftTable = joinTable; | ||||
|             } else { | ||||
|                 processOtherFromItem(joinItem); | ||||
|                 leftTable = null; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return mainTables; | ||||
|     } | ||||
|  | ||||
|     // ========== 和 TenantLineInnerInterceptor 存在差异的逻辑:关键,实现权限条件的拼接 ========== | ||||
|  | ||||
|     /** | ||||
|      * 处理条件 | ||||
|      * | ||||
|      * @param currentExpression 当前 where 条件 | ||||
|      * @param table             单个表 | ||||
|      */ | ||||
|     protected Expression builderExpression(Expression currentExpression, Table table) { | ||||
|         return this.builderExpression(currentExpression, Collections.singletonList(table)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 处理条件 | ||||
|      * | ||||
|      * @param currentExpression 当前 where 条件 | ||||
|      * @param tables 多个表 | ||||
|      */ | ||||
|     protected Expression builderExpression(Expression currentExpression, List<Table> tables) { | ||||
|         // 没有表需要处理直接返回 | ||||
|         if (CollectionUtils.isEmpty(tables)) { | ||||
|             return currentExpression; | ||||
|         } | ||||
|  | ||||
|         // 第一步,获得 Table 对应的数据权限条件 | ||||
|         Expression dataPermissionExpression = null; | ||||
|         for (Table table : tables) { | ||||
|             // 构建每个表的权限 Expression 条件 | ||||
|             Expression expression = buildDataPermissionExpression(table); | ||||
|             if (expression == null) { | ||||
|                 continue; | ||||
|             } | ||||
|             // 合并到 dataPermissionExpression 中 | ||||
|             dataPermissionExpression = dataPermissionExpression == null ? expression | ||||
|                     : new AndExpression(dataPermissionExpression, expression); | ||||
|         } | ||||
|  | ||||
|         // 第二步,合并多个 Expression 条件 | ||||
|         if (dataPermissionExpression == null) { | ||||
|             return currentExpression; | ||||
|         } | ||||
|         if (currentExpression == null) { | ||||
|             return dataPermissionExpression; | ||||
|         } | ||||
|         // ① 如果表达式为 Or,则需要 (currentExpression) AND dataPermissionExpression | ||||
|         if (currentExpression instanceof OrExpression) { | ||||
|             return new AndExpression(new Parenthesis(currentExpression), dataPermissionExpression); | ||||
|         } | ||||
|         // ② 如果表达式为 And,则直接返回 where AND dataPermissionExpression | ||||
|         return new AndExpression(currentExpression, dataPermissionExpression); | ||||
|     protected Expression getUpdateOrDeleteExpression(final Table table, final Expression where, final String whereSegment) { | ||||
|         return andExpression(table, where, whereSegment); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -491,7 +146,8 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme | ||||
|      * @param table 表 | ||||
|      * @return Expression 过滤条件 | ||||
|      */ | ||||
|     private Expression buildDataPermissionExpression(Table table) { | ||||
|     @Override | ||||
|     public Expression buildTableExpression(Table table, Expression where, String whereSegment) { | ||||
|         // 生成条件 | ||||
|         Expression allExpression = null; | ||||
|         for (DataPermissionRule rule : ContextHolder.getRules()) { | ||||
|   | ||||
| @@ -156,7 +156,8 @@ public class DeptDataPermissionRule implements DataPermissionRule { | ||||
|         } | ||||
|         // 拼接条件 | ||||
|         return new InExpression(MyBatisUtils.buildColumn(tableName, tableAlias, columnName), | ||||
|                 new ExpressionList(CollectionUtils.convertList(deptIds, LongValue::new))); | ||||
|                 // Parenthesis 的目的,是提供 (1,2,3) 的 () 左右括号 | ||||
|                 new Parenthesis(new ExpressionList<>(CollectionUtils.convertList(deptIds, LongValue::new)))); | ||||
|     } | ||||
|  | ||||
|     private Expression buildUserExpression(String tableName, Alias tableAlias, Boolean self, Long userId) { | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; | ||||
| import net.sf.jsqlparser.expression.Alias; | ||||
| import net.sf.jsqlparser.expression.Expression; | ||||
| import net.sf.jsqlparser.expression.LongValue; | ||||
| import net.sf.jsqlparser.expression.Parenthesis; | ||||
| import net.sf.jsqlparser.expression.operators.relational.EqualsTo; | ||||
| import net.sf.jsqlparser.expression.operators.relational.ExpressionList; | ||||
| import net.sf.jsqlparser.expression.operators.relational.InExpression; | ||||
| @@ -71,9 +72,9 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest | ||||
|             @Override | ||||
|             public Expression getExpression(String tableName, Alias tableAlias) { | ||||
|                 Column column = MyBatisUtils.buildColumn(tableName, tableAlias, COLUMN); | ||||
|                 ExpressionList values = new ExpressionList(new LongValue(10L), | ||||
|                 ExpressionList<LongValue> values = new ExpressionList<>(new LongValue(10L), | ||||
|                         new LongValue(20L)); | ||||
|                 return new InExpression(column, values); | ||||
|                 return new InExpression(column, new Parenthesis((values))); | ||||
|             } | ||||
|  | ||||
|         }; | ||||
| @@ -262,7 +263,7 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest | ||||
|                         "right join entity2 e2 on e1.id = e2.id", | ||||
|                 "SELECT * FROM entity e " + | ||||
|                         "LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " + | ||||
|                         "RIGHT JOIN entity2 e2 ON e1.id = e2.id AND e1.tenant_id = 1 " + | ||||
|                         "RIGHT JOIN entity2 e2 ON e1.id = e2.id AND e.tenant_id = 1 " + | ||||
|                         "WHERE e2.tenant_id = 1"); | ||||
|  | ||||
|         assertSql("SELECT * FROM entity e " + | ||||
|   | ||||
| @@ -185,7 +185,7 @@ public interface BaseMapperX<T> extends MPJBaseMapper<T> { | ||||
|         return Db.updateBatchById(entities, size); | ||||
|     } | ||||
|  | ||||
|     default Boolean insertOrUpdate(T entity) { | ||||
|     default boolean insertOrUpdate(T entity) { | ||||
|         return Db.saveOrUpdate(entity); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -1,31 +0,0 @@ | ||||
| package cn.iocoder.yudao.framework.mybatis.core.type; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | ||||
| import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler; | ||||
| import com.fasterxml.jackson.core.type.TypeReference; | ||||
|  | ||||
| import java.util.Set; | ||||
|  | ||||
| /** | ||||
|  * 参考 {@link com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler} 实现 | ||||
|  * 在我们将字符串反序列化为 Set 并且泛型为 Long 时,如果每个元素的数值太小,会被处理成 Integer 类型,导致可能存在隐性的 BUG。 | ||||
|  * | ||||
|  * 例如说哦,SysUserDO 的 postIds 属性 | ||||
|  * | ||||
|  * @author 芋道源码 | ||||
|  */ | ||||
| public class JsonLongSetTypeHandler extends AbstractJsonTypeHandler<Object> { | ||||
|  | ||||
|     private static final TypeReference<Set<Long>> TYPE_REFERENCE = new TypeReference<Set<Long>>(){}; | ||||
|  | ||||
|     @Override | ||||
|     protected Object parse(String json) { | ||||
|         return JsonUtils.parseObject(json, TYPE_REFERENCE); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected String toJson(Object obj) { | ||||
|         return JsonUtils.toJsonString(obj); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1,7 +1,6 @@ | ||||
| package cn.iocoder.yudao.module.ai.dal.dataobject.image; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.ai.core.model.midjourney.api.MidjourneyApi; | ||||
| import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | ||||
| import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||||
| import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO; | ||||
| import cn.iocoder.yudao.module.ai.enums.image.AiImageStatusEnum; | ||||
| @@ -10,7 +9,6 @@ import com.baomidou.mybatisplus.annotation.IdType; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler; | ||||
| import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | ||||
| import lombok.Data; | ||||
| import org.springframework.ai.openai.OpenAiImageOptions; | ||||
| @@ -107,7 +105,7 @@ public class AiImageDO extends BaseDO { | ||||
|     /** | ||||
|      * mj buttons 按钮 | ||||
|      */ | ||||
|     @TableField(typeHandler = ButtonTypeHandler.class) | ||||
|     @TableField(typeHandler = JacksonTypeHandler.class) | ||||
|     private List<MidjourneyApi.Button> buttons; | ||||
|  | ||||
|     /** | ||||
| @@ -117,19 +115,5 @@ public class AiImageDO extends BaseDO { | ||||
|      */ | ||||
|     private String taskId; | ||||
|  | ||||
|     public static class ButtonTypeHandler extends AbstractJsonTypeHandler<Object> { | ||||
|  | ||||
|         @Override | ||||
|         protected Object parse(String json) { | ||||
|             return JsonUtils.parseArray(json, MidjourneyApi.Button.class); | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         protected String toJson(Object obj) { | ||||
|             return JsonUtils.toJsonString(obj); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -2,11 +2,14 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.definition; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||||
| import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||||
| import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import lombok.*; | ||||
| import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | ||||
| import lombok.AllArgsConstructor; | ||||
| import lombok.Builder; | ||||
| import lombok.Data; | ||||
| import lombok.NoArgsConstructor; | ||||
|  | ||||
| import java.util.Set; | ||||
|  | ||||
| @@ -44,7 +47,7 @@ public class BpmUserGroupDO extends BaseDO { | ||||
|     /** | ||||
|      * 成员用户编号数组 | ||||
|      */ | ||||
|     @TableField(typeHandler = JsonLongSetTypeHandler.class) | ||||
|     @TableField(typeHandler = JacksonTypeHandler.class) | ||||
|     private Set<Long> userIds; | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -17,6 +17,8 @@ import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler; | ||||
| import com.fasterxml.jackson.core.type.TypeReference; | ||||
| import lombok.*; | ||||
|  | ||||
| import java.lang.reflect.Field; | ||||
|  | ||||
| /** | ||||
|  * 文件配置表 | ||||
|  * | ||||
| @@ -65,8 +67,16 @@ public class FileConfigDO extends BaseDO { | ||||
|  | ||||
|     public static class FileClientConfigTypeHandler extends AbstractJsonTypeHandler<Object> { | ||||
|  | ||||
|         public FileClientConfigTypeHandler(Class<?> type) { | ||||
|             super(type); | ||||
|         } | ||||
|  | ||||
|         public FileClientConfigTypeHandler(Class<?> type, Field field) { | ||||
|             super(type, field); | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         protected Object parse(String json) { | ||||
|         public Object parse(String json) { | ||||
|             FileClientConfig config = JsonUtils.parseObjectQuietly(json, new TypeReference<>() {}); | ||||
|             if (config != null) { | ||||
|                 return config; | ||||
| @@ -92,7 +102,7 @@ public class FileConfigDO extends BaseDO { | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         protected String toJson(Object obj) { | ||||
|         public String toJson(Object obj) { | ||||
|             return JsonUtils.toJsonString(obj); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -100,7 +100,7 @@ public class ProductCommentDO extends BaseDO { | ||||
|      * | ||||
|      * 关联 {@link ProductSkuDO#getProperties()} | ||||
|      */ | ||||
|     @TableField(typeHandler = ProductSkuDO.PropertyTypeHandler.class) | ||||
|     @TableField(typeHandler = JacksonTypeHandler.class) | ||||
|     private List<ProductSkuDO.Property> skuProperties; | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| package cn.iocoder.yudao.module.product.dal.dataobject.sku; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | ||||
| import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||||
| import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; | ||||
| import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; | ||||
| @@ -9,7 +8,7 @@ import com.baomidou.mybatisplus.annotation.KeySequence; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler; | ||||
| import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | ||||
| import lombok.*; | ||||
|  | ||||
| import java.util.List; | ||||
| @@ -43,7 +42,7 @@ public class ProductSkuDO extends BaseDO { | ||||
|     /** | ||||
|      * 属性数组,JSON 格式 | ||||
|      */ | ||||
|     @TableField(typeHandler = PropertyTypeHandler.class) | ||||
|     @TableField(typeHandler = JacksonTypeHandler.class) | ||||
|     private List<Property> properties; | ||||
|     /** | ||||
|      * 商品价格,单位:分 | ||||
| @@ -131,21 +130,6 @@ public class ProductSkuDO extends BaseDO { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     // TODO @芋艿:可以找一些新的思路 | ||||
|     public static class PropertyTypeHandler extends AbstractJsonTypeHandler<Object> { | ||||
|  | ||||
|         @Override | ||||
|         protected Object parse(String json) { | ||||
|             return JsonUtils.parseArray(json, Property.class); | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         protected String toJson(Object obj) { | ||||
|             return JsonUtils.toJsonString(obj); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     // TODO 芋艿:integral from y | ||||
|     // TODO 芋艿:pinkPrice from y | ||||
|     // TODO 芋艿:seckillPrice from y | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| package cn.iocoder.yudao.module.promotion.dal.dataobject.reward; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | ||||
| import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||||
| import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; | ||||
| import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; | ||||
| @@ -10,7 +9,7 @@ import com.baomidou.mybatisplus.annotation.KeySequence; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler; | ||||
| import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
|  | ||||
| @@ -76,7 +75,7 @@ public class RewardActivityDO extends BaseDO { | ||||
|     /** | ||||
|      * 优惠规则的数组 | ||||
|      */ | ||||
|     @TableField(typeHandler = RuleTypeHandler.class) | ||||
|     @TableField(typeHandler = JacksonTypeHandler.class) | ||||
|     private List<Rule> rules; | ||||
|  | ||||
|     /** | ||||
| @@ -115,19 +114,4 @@ public class RewardActivityDO extends BaseDO { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     // TODO @芋艿:可以找一些新的思路 | ||||
|     public static class RuleTypeHandler extends AbstractJsonTypeHandler<List<Rule>> { | ||||
|  | ||||
|         @Override | ||||
|         protected List<Rule> parse(String json) { | ||||
|             return JsonUtils.parseArray(json, Rule.class); | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         protected String toJson(List<Rule> obj) { | ||||
|             return JsonUtils.toJsonString(obj); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -124,7 +124,7 @@ public class AfterSaleDO extends BaseDO { | ||||
|      * | ||||
|      * 冗余 {@link TradeOrderItemDO#getProperties()} | ||||
|      */ | ||||
|     @TableField(typeHandler = TradeOrderItemDO.PropertyTypeHandler.class) | ||||
|     @TableField(typeHandler = JacksonTypeHandler.class) | ||||
|     private List<TradeOrderItemDO.Property> properties; | ||||
|     /** | ||||
|      * 商品图片 | ||||
|   | ||||
| @@ -1,13 +1,12 @@ | ||||
| package cn.iocoder.yudao.module.trade.dal.dataobject.order; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | ||||
| import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||||
| import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleDO; | ||||
| import cn.iocoder.yudao.module.trade.dal.dataobject.cart.CartDO; | ||||
| import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler; | ||||
| import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| import lombok.experimental.Accessors; | ||||
| @@ -74,7 +73,7 @@ public class TradeOrderItemDO extends BaseDO { | ||||
|      * | ||||
|      * 冗余 ProductSkuDO 的 properties 字段 | ||||
|      */ | ||||
|     @TableField(typeHandler = PropertyTypeHandler.class) | ||||
|     @TableField(typeHandler = JacksonTypeHandler.class) | ||||
|     private List<Property> properties; | ||||
|     /** | ||||
|      * 商品图片 | ||||
| @@ -210,20 +209,5 @@ public class TradeOrderItemDO extends BaseDO { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     // TODO @芋艿:可以找一些新的思路 | ||||
|     public static class PropertyTypeHandler extends AbstractJsonTypeHandler<List<Property>> { | ||||
|  | ||||
|         @Override | ||||
|         protected List<Property> parse(String json) { | ||||
|             return JsonUtils.parseArray(json, Property.class); | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         protected String toJson(List<Property> obj) { | ||||
|             return JsonUtils.toJsonString(obj); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -2,12 +2,12 @@ package cn.iocoder.yudao.module.mp.controller.admin.message.vo.message; | ||||
|  | ||||
| import cn.iocoder.yudao.module.mp.dal.dataobject.message.MpMessageDO; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
| import lombok.Data; | ||||
| import me.chanjar.weixin.common.api.WxConsts; | ||||
|  | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.Date; | ||||
| import java.util.List; | ||||
|  | ||||
| @Schema(description = "管理后台 - 公众号消息 Response VO") | ||||
| @@ -81,7 +81,7 @@ public class MpMessageRespVO { | ||||
|      * | ||||
|      * 消息类型为 {@link WxConsts.XmlMsgType} 的 NEWS | ||||
|      */ | ||||
|     @TableField(typeHandler = MpMessageDO.ArticleTypeHandler.class) | ||||
|     @TableField(typeHandler = JacksonTypeHandler.class) | ||||
|     private List<MpMessageDO.Article> articles; | ||||
|  | ||||
|     @Schema(description = "音乐链接 消息类型为 music 时,才有值", example = "https://www.iocoder.cn/xxx.mp3") | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.annotation.KeySequence; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| import lombok.ToString; | ||||
| @@ -163,7 +164,7 @@ public class MpMenuDO extends BaseDO { | ||||
|      * | ||||
|      * 消息类型为 {@link WxConsts.XmlMsgType} 的 NEWS | ||||
|      */ | ||||
|     @TableField(typeHandler = MpMessageDO.ArticleTypeHandler.class) | ||||
|     @TableField(typeHandler = JacksonTypeHandler.class) | ||||
|     private List<MpMessageDO.Article> replyArticles; | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.annotation.KeySequence; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| import lombok.ToString; | ||||
| @@ -143,7 +144,7 @@ public class MpAutoReplyDO extends BaseDO { | ||||
|      * | ||||
|      * 消息类型为 {@link WxConsts.XmlMsgType} 的 NEWS | ||||
|      */ | ||||
|     @TableField(typeHandler = MpMessageDO.ArticleTypeHandler.class) | ||||
|     @TableField(typeHandler = JacksonTypeHandler.class) | ||||
|     private List<MpMessageDO.Article> responseArticles; | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| package cn.iocoder.yudao.module.mp.dal.dataobject.message; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | ||||
| import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||||
| import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO; | ||||
| import cn.iocoder.yudao.module.mp.dal.dataobject.user.MpUserDO; | ||||
| @@ -9,12 +8,14 @@ import com.baomidou.mybatisplus.annotation.KeySequence; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler; | ||||
| import lombok.*; | ||||
| import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | ||||
| import jakarta.validation.constraints.NotEmpty; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| import lombok.ToString; | ||||
| import me.chanjar.weixin.common.api.WxConsts; | ||||
| import me.chanjar.weixin.mp.builder.kefu.NewsBuilder; | ||||
|  | ||||
| import jakarta.validation.constraints.NotEmpty; | ||||
| import java.io.Serializable; | ||||
| import java.util.List; | ||||
|  | ||||
| @@ -173,7 +174,7 @@ public class MpMessageDO extends BaseDO { | ||||
|      * | ||||
|      * 消息类型为 {@link WxConsts.XmlMsgType} 的 NEWS | ||||
|      */ | ||||
|     @TableField(typeHandler = ArticleTypeHandler.class) | ||||
|     @TableField(typeHandler = JacksonTypeHandler.class) | ||||
|     private List<Article> articles; | ||||
|  | ||||
|     /** | ||||
| @@ -238,18 +239,4 @@ public class MpMessageDO extends BaseDO { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     // TODO @芋艿:可以找一些新的思路 | ||||
|     public static class ArticleTypeHandler extends AbstractJsonTypeHandler<List<Article>> { | ||||
|  | ||||
|         @Override | ||||
|         protected List<Article> parse(String json) { | ||||
|             return JsonUtils.parseArray(json, Article.class); | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         protected String toJson(List<Article> obj) { | ||||
|             return JsonUtils.toJsonString(obj); | ||||
|         } | ||||
|  | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,14 +1,14 @@ | ||||
| package cn.iocoder.yudao.module.system.dal.dataobject.permission; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||||
| import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler; | ||||
| import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum; | ||||
| import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; | ||||
| import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum; | ||||
| import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum; | ||||
| import com.baomidou.mybatisplus.annotation.KeySequence; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
|  | ||||
| @@ -72,7 +72,7 @@ public class RoleDO extends TenantBaseDO { | ||||
|      * | ||||
|      * 适用于 {@link #dataScope} 的值为 {@link DataScopeEnum#DEPT_CUSTOM} 时 | ||||
|      */ | ||||
|     @TableField(typeHandler = JsonLongSetTypeHandler.class) | ||||
|     @TableField(typeHandler = JacksonTypeHandler.class) | ||||
|     private Set<Long> dataScopeDeptIds; | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -2,10 +2,10 @@ package cn.iocoder.yudao.module.system.dal.dataobject.tenant; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||||
| import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||||
| import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler; | ||||
| import com.baomidou.mybatisplus.annotation.KeySequence; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | ||||
| import lombok.*; | ||||
|  | ||||
| import java.util.Set; | ||||
| @@ -46,7 +46,7 @@ public class TenantPackageDO extends BaseDO { | ||||
|     /** | ||||
|      * 关联的菜单编号 | ||||
|      */ | ||||
|     @TableField(typeHandler = JsonLongSetTypeHandler.class) | ||||
|     @TableField(typeHandler = JacksonTypeHandler.class) | ||||
|     private Set<Long> menuIds; | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,13 +1,13 @@ | ||||
| package cn.iocoder.yudao.module.system.dal.dataobject.user; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||||
| import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler; | ||||
| import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; | ||||
| import cn.iocoder.yudao.module.system.enums.common.SexEnum; | ||||
| import com.baomidou.mybatisplus.annotation.KeySequence; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | ||||
| import lombok.*; | ||||
| import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | ||||
|  | ||||
| @@ -58,7 +58,7 @@ public class AdminUserDO extends TenantBaseDO { | ||||
|     /** | ||||
|      * 岗位编号数组 | ||||
|      */ | ||||
|     @TableField(typeHandler = JsonLongSetTypeHandler.class) | ||||
|     @TableField(typeHandler = JacksonTypeHandler.class) | ||||
|     private Set<Long> postIds; | ||||
|     /** | ||||
|      * 用户邮箱 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV