|
@@ -0,0 +1,124 @@
|
|
|
+/*
|
|
|
+ * Copyright (c) 2018-2025, lengleng All rights reserved.
|
|
|
+ *
|
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
|
+ * modification, are permitted provided that the following conditions are met:
|
|
|
+ *
|
|
|
+ * Redistributions of source code must retain the above copyright notice,
|
|
|
+ * this list of conditions and the following disclaimer.
|
|
|
+ * Redistributions in binary form must reproduce the above copyright
|
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
|
+ * Neither the name of the pig4cloud.com developer nor the names of its
|
|
|
+ * contributors may be used to endorse or promote products derived from
|
|
|
+ * this software without specific prior written permission.
|
|
|
+ * Author: lengleng (wangiegie@gmail.com)
|
|
|
+ */
|
|
|
+
|
|
|
+package com.pig4cloud.pigx.common.core.datascope;
|
|
|
+
|
|
|
+import cn.hutool.core.collection.CollectionUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import com.baomidou.mybatisplus.plugins.SqlParserHandler;
|
|
|
+import com.baomidou.mybatisplus.toolkit.PluginUtils;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.ibatis.executor.statement.StatementHandler;
|
|
|
+import org.apache.ibatis.mapping.BoundSql;
|
|
|
+import org.apache.ibatis.mapping.MappedStatement;
|
|
|
+import org.apache.ibatis.mapping.SqlCommandType;
|
|
|
+import org.apache.ibatis.plugin.*;
|
|
|
+import org.apache.ibatis.reflection.MetaObject;
|
|
|
+import org.apache.ibatis.reflection.SystemMetaObject;
|
|
|
+
|
|
|
+import java.sql.Connection;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Properties;
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author lengleng
|
|
|
+ * @date 2018/8/30
|
|
|
+ * <p>
|
|
|
+ * mybatis 数据权限拦截器
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
|
|
|
+public class DataScopeInterceptor extends SqlParserHandler implements Interceptor {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Object intercept(Invocation invocation) throws Throwable {
|
|
|
+ StatementHandler statementHandler = (StatementHandler) PluginUtils.realTarget(invocation.getTarget());
|
|
|
+ MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
|
|
|
+ this.sqlParser(metaObject);
|
|
|
+ // 先判断是不是SELECT操作
|
|
|
+ MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
|
|
|
+ if (!SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())) {
|
|
|
+ return invocation.proceed();
|
|
|
+ }
|
|
|
+
|
|
|
+ BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql");
|
|
|
+ String originalSql = boundSql.getSql();
|
|
|
+ Object parameterObject = boundSql.getParameterObject();
|
|
|
+
|
|
|
+ //查找参数中包含DataScope类型的参数
|
|
|
+ DataScope dataScope = findDataScopeObject(parameterObject);
|
|
|
+
|
|
|
+ if (dataScope == null) {
|
|
|
+ return invocation.proceed();
|
|
|
+ } else {
|
|
|
+ String scopeName = dataScope.getScopeName();
|
|
|
+ List<Integer> deptIds = dataScope.getDeptIds();
|
|
|
+ if (StrUtil.isNotBlank(scopeName) && CollectionUtil.isNotEmpty(deptIds)) {
|
|
|
+ String join = CollectionUtil.join(deptIds, ",");
|
|
|
+ originalSql = "select * from (" + originalSql + ") temp_data_scope where temp_data_scope." + scopeName + " in (" + join + ")";
|
|
|
+ metaObject.setValue("delegate.boundSql.sql", originalSql);
|
|
|
+ }
|
|
|
+ return invocation.proceed();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成拦截对象的代理
|
|
|
+ *
|
|
|
+ * @param target 目标对象
|
|
|
+ * @return 代理对象
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public Object plugin(Object target) {
|
|
|
+ if (target instanceof StatementHandler) {
|
|
|
+ return Plugin.wrap(target, this);
|
|
|
+ }
|
|
|
+ return target;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * mybatis配置的属性
|
|
|
+ *
|
|
|
+ * @param properties mybatis配置的属性
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void setProperties(Properties properties) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查找参数是否包括DataScope对象
|
|
|
+ *
|
|
|
+ * @param parameterObj 参数列表
|
|
|
+ * @return DataScope
|
|
|
+ */
|
|
|
+ private DataScope findDataScopeObject(Object parameterObj) {
|
|
|
+ if (parameterObj instanceof DataScope) {
|
|
|
+ return (DataScope) parameterObj;
|
|
|
+ } else if (parameterObj instanceof Map) {
|
|
|
+ for (Object val : ((Map<?, ?>) parameterObj).values()) {
|
|
|
+ if (val instanceof DataScope) {
|
|
|
+ return (DataScope) val;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|