浏览代码

杰生重构

24282 2 年之前
父节点
当前提交
6beaa09018

+ 436 - 0
hx-service/storage-restructure/src/main/java/com/fjhx/config/LogicDeleteInterceptor.java

@@ -0,0 +1,436 @@
+package com.fjhx.config;
+
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import net.sf.jsqlparser.JSQLParserException;
+import net.sf.jsqlparser.expression.*;
+import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
+import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
+import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
+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.parser.CCJSqlParserUtil;
+import net.sf.jsqlparser.schema.Column;
+import net.sf.jsqlparser.schema.Table;
+import net.sf.jsqlparser.statement.select.*;
+import org.apache.ibatis.executor.Executor;
+import org.apache.ibatis.mapping.BoundSql;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.session.ResultHandler;
+import org.apache.ibatis.session.RowBounds;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Component
+@Slf4j
+public class LogicDeleteInterceptor implements InnerInterceptor {
+
+    private static final String delFlagName = "del_flag";
+    private static final Expression delFlagValue = new LongValue(0);
+    private final List<String> excludeDelFlagTableNameList;
+
+    public LogicDeleteInterceptor(List<String> excludeDelFlagTableNameList) {
+        this.excludeDelFlagTableNameList = excludeDelFlagTableNameList;
+    }
+
+    @SneakyThrows
+    @Override
+    public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds,
+                            ResultHandler resultHandler, BoundSql boundSql) {
+
+        PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
+        mpBs.sql(handleSql(boundSql.getSql()));
+    }
+
+    /**
+     * 改写SQL
+     * {@link com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor  processSelect 方法}
+     *
+     * @param sql 执行的SQL语句
+     * @return 处理后的SQL
+     */
+    private String handleSql(String sql) throws JSQLParserException {
+        Select select = (Select) CCJSqlParserUtil.parse(sql);
+        processSelectBody(select.getSelectBody());
+        List<WithItem> withItemsList = select.getWithItemsList();
+        if (!CollectionUtils.isEmpty(withItemsList)) {
+            withItemsList.forEach(this::processSelectBody);
+        }
+        return select.toString();
+    }
+
+    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) && (where == null || !where.toString().contains(delFlagName))) {
+            plainSelect.setWhere(builderExpression(where, 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());
+            }
+        }
+    }
+
+    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;
+    }
+
+    /**
+     * 处理子查询等
+     */
+    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) {
+            log.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;
+    }
+
+
+    /**
+     * 处理函数
+     * <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);
+                }
+            });
+        }
+    }
+
+    /**
+     * 处理 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;
+    }
+
+    /**
+     * 处理条件
+     */
+    protected Expression builderExpression(Expression currentExpression, List<Table> tables) {
+        // 没有表需要处理直接返回
+        if (CollectionUtils.isEmpty(tables)) {
+            return currentExpression;
+        }
+        // 构造每张表的条件
+        List<Table> tempTables = tables.stream()
+                .filter(x -> !excludeDelFlagTableNameList.contains(x.getName()))
+                .collect(Collectors.toList());
+
+        // 没有表需要处理直接返回
+        if (CollectionUtils.isEmpty(tempTables)) {
+            return currentExpression;
+        }
+
+        List<EqualsTo> equalsTos = tempTables.stream()
+                .map(item -> new EqualsTo(getAliasColumn(item), delFlagValue))
+                .collect(Collectors.toList());
+
+        // 注入的表达式
+        Expression injectExpression = equalsTos.get(0);
+        // 如果有多表,则用 and 连接
+        if (equalsTos.size() > 1) {
+            for (int i = 1; i < equalsTos.size(); i++) {
+                injectExpression = new AndExpression(injectExpression, equalsTos.get(i));
+            }
+        }
+
+        if (currentExpression == null) {
+            return injectExpression;
+        }
+        if (currentExpression instanceof OrExpression) {
+            return new AndExpression(new Parenthesis(currentExpression), injectExpression);
+        } else {
+            return new AndExpression(currentExpression, injectExpression);
+        }
+    }
+
+    /**
+     * 租户字段别名设置
+     * <p>tenantId 或 tableAlias.tenantId</p>
+     *
+     * @param table 表对象
+     * @return 字段
+     */
+    protected Column getAliasColumn(Table table) {
+        StringBuilder column = new StringBuilder();
+        // 为了兼容隐式内连接,没有别名时条件就需要加上表名
+        if (table.getAlias() != null) {
+            column.append(table.getAlias().getName());
+        } else {
+            column.append(table.getName());
+        }
+        column.append(StringPool.DOT).append(delFlagName);
+        return new Column(column.toString());
+    }
+
+}

+ 40 - 0
hx-service/storage-restructure/src/main/java/com/fjhx/config/MybatisConfig.java

@@ -0,0 +1,40 @@
+package com.fjhx.config;
+
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.Arrays;
+import java.util.List;
+
+@Configuration
+public class MybatisConfig {
+
+    /**
+     * 排除不要拼接逻辑删除的表集合
+     */
+    private static final List<String> excludeDelFlagTableNameList = Arrays.asList("common_config", "v3_plan", "v3_plan_statistics");
+
+    /**
+     * 租户插件
+     */
+    @Bean
+    public MybatisPlusInterceptor mybatisPlusInterceptorPage() {
+        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+
+        // 拼接逻辑删除字段
+        interceptor.addInnerInterceptor(new LogicDeleteInterceptor(excludeDelFlagTableNameList));
+
+        // 分页
+        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
+
+        // 乐观锁
+        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
+
+        return interceptor;
+    }
+
+}

+ 1 - 0
hx-service/storage-restructure/src/main/java/com/fjhx/service/material/impl/MaterialServiceImpl.java

@@ -41,6 +41,7 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
         QueryWrapper<Material> wrapper = Wrappers.query();
 
         WrapperUtil.init(condition, wrapper)
+                .eq("material_classify_id", "materialClassifyId")
                 .keyword("code", "name");
 
         wrapper.orderByAsc("code");

+ 0 - 1
hx-service/storage-restructure/src/main/java/com/fjhx/service/supplier/impl/SupplierPriceServiceImpl.java

@@ -64,7 +64,6 @@ public class SupplierPriceServiceImpl extends ServiceImpl<SupplierPriceMapper, S
         return WrapperUtil.init(condition)
                 .keyword("m.name", "m.code", "s.name")
                 .eq("s.id", "supplierId")
-                .notDelete("sp")
                 .createTimeDesc()
                 .getWrapper();
     }

+ 9 - 10
hx-service/storage/src/main/java/com/fjhx/stock/service/impl/StockWaterServiceImpl.java

@@ -634,8 +634,7 @@ public class StockWaterServiceImpl extends ServiceImpl<StockWaterMapper, StockWa
         }
 
         // 查询出库明细
-        List<String> waterIdList = records.stream().map(item -> Convert.toStr(item.get("waterId")))
-                .collect(Collectors.toList());
+        List<String> waterIdList = records.stream().map(item -> Convert.toStr(item.get("waterId"))).collect(Collectors.toList());
 
         Map<String, List<StockWaterdetial>> waterIdGroup = stockWaterdetialService.getKGroup(
                 StockWaterdetial::getWaterId,
@@ -644,9 +643,8 @@ public class StockWaterServiceImpl extends ServiceImpl<StockWaterMapper, StockWa
                         .eq(StockWaterdetial::getIsDelete, 0));
 
         records.forEach(item -> {
-            String waterId = Convert.toStr(item.get("waterId"));
-            List<StockWaterdetial> stockWaterdetials = waterIdGroup.get(waterId);
-            item.put("detailsList", stockWaterdetials);
+            String waterId = Convert.toStr(item.get("waterId"), "");
+            item.put("detailsList", waterIdGroup.get(waterId));
         });
 
         return page;
@@ -698,11 +696,12 @@ public class StockWaterServiceImpl extends ServiceImpl<StockWaterMapper, StockWa
                     if (ObjectUtil.isEmpty(stockChangeType)) {
                         q.in("sw.StockChangeType", 20, 23, 26, 27);
                     } else {
-                        if (stockChangeType == 20) {
-                            q.in("sw.StockChangeType", 20, 23);
-                        } else {
-                            q.eq("sw.StockChangeType", stockChangeType);
-                        }
+                        // if (stockChangeType == 20) {
+                        //     q.in("sw.StockChangeType", 20, 23);
+                        // } else {
+                        //     q.eq("sw.StockChangeType", stockChangeType);
+                        // }
+                        q.eq("sw.StockChangeType", stockChangeType);
                     }
                 })
                 .keyword(new KeywordData("m.name"), new KeywordData("m.code"))