/* * 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 ([email protected]) */ package com.github.pig.common.bean.interceptor; import com.baomidou.mybatisplus.plugins.SqlParserHandler; import com.baomidou.mybatisplus.toolkit.PluginUtils; import com.xiaoleilu.hutool.collection.CollectionUtil; import com.xiaoleilu.hutool.util.StrUtil; 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/1/19 * 数据权限插件,guns */ @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; } }