mirror of
https://gitee.com/dromara/RuoYi-Vue-Plus.git
synced 2026-09-19 17:58:17 +08:00
Pre Merge pull request !563 from Colin/feat-customSQL
This commit is contained in:
commit
593d2c9a59
@ -0,0 +1,41 @@
|
|||||||
|
package org.dromara.test.mapper;
|
||||||
|
|
||||||
|
public class CustomSqlTest {
|
||||||
|
/**
|
||||||
|
* mapper 接口
|
||||||
|
* @Mapper
|
||||||
|
* public interface ILoanMapper extends BaseMapper<Loan> {
|
||||||
|
* @DataPermission({
|
||||||
|
* @DataColumn(key = DataColumn.CUSTOM_SQL, value = "(#{#trackerId} = #{#user.userId} or #{#salespersonId} = #{#user.userId})"),
|
||||||
|
* @DataColumn(key = {"trackerId", "salespersonId"}, value = {"l.tracker_id", "l.salesperson_id"}),
|
||||||
|
* })
|
||||||
|
* Page<Loan> selectPageLoanList(@Param("page") Page<Loan> page, @Param(Constants.WRAPPER) Wrapper<Loan> queryWrapper);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* mapper 文件
|
||||||
|
* <select id="selectPageLoanList" resultType="com.smart330.zr.loan.domain.entity.Loan">
|
||||||
|
* select
|
||||||
|
* <if test="ew.getSqlSelect != null">
|
||||||
|
* ${ew.getSqlSelect}
|
||||||
|
* </if>
|
||||||
|
* <if test="ew.getSqlSelect == null">
|
||||||
|
* *
|
||||||
|
* </if>
|
||||||
|
* from zr_loan l
|
||||||
|
* ${ew.getCustomSqlSegment}
|
||||||
|
* </select>
|
||||||
|
*
|
||||||
|
* 实体
|
||||||
|
* public class Loan extends TenantEntity {
|
||||||
|
* private Long id;
|
||||||
|
* //业务员
|
||||||
|
* private Long salespersonId;
|
||||||
|
* //跟单员
|
||||||
|
* private Long trackerId;
|
||||||
|
* .....
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* //结果: 业务员 与 跟单员都只能看自己的数据,但每条数据 既有跟单员也有业务员
|
||||||
|
* select * from zr_loan where (l.tracker_id = 1 or l.salesperson_id = 1)
|
||||||
|
*/
|
||||||
|
}
|
||||||
@ -15,6 +15,7 @@ import java.lang.annotation.*;
|
|||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Documented
|
@Documented
|
||||||
public @interface DataColumn {
|
public @interface DataColumn {
|
||||||
|
String CUSTOM_SQL = "CustomSql";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据权限模板的占位符关键字,默认为 "deptName"
|
* 数据权限模板的占位符关键字,默认为 "deptName"
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import lombok.AllArgsConstructor;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.dromara.common.core.domain.model.LoginUser;
|
import org.dromara.common.core.domain.model.LoginUser;
|
||||||
import org.dromara.common.core.utils.StringUtils;
|
import org.dromara.common.core.utils.StringUtils;
|
||||||
|
import org.dromara.common.mybatis.annotation.DataColumn;
|
||||||
import org.dromara.common.mybatis.helper.DataPermissionHelper;
|
import org.dromara.common.mybatis.helper.DataPermissionHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -56,7 +57,12 @@ public enum DataScopeType {
|
|||||||
* 使用 SpEL 表达式:`#{#userName} = #{#user.userId}`
|
* 使用 SpEL 表达式:`#{#userName} = #{#user.userId}`
|
||||||
* 如果不满足条件,则使用默认 SQL 表达式:`1 = 0`
|
* 如果不满足条件,则使用默认 SQL 表达式:`1 = 0`
|
||||||
*/
|
*/
|
||||||
SELF("5", " #{#userName} = #{#user.userId} ", " 1 = 0 ");
|
SELF("5", " #{#userName} = #{#user.userId} ", " 1 = 0 "),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 弹性数据权限(通过自定义SQL实现)
|
||||||
|
*/
|
||||||
|
CUSTOM_SQL("6", " {" + DataColumn.CUSTOM_SQL + "} ", " 1 = 0 ");
|
||||||
|
|
||||||
private final String code;
|
private final String code;
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package org.dromara.common.mybatis.handler;
|
|||||||
import cn.hutool.core.annotation.AnnotationUtil;
|
import cn.hutool.core.annotation.AnnotationUtil;
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.sf.jsqlparser.JSQLParserException;
|
import net.sf.jsqlparser.JSQLParserException;
|
||||||
import net.sf.jsqlparser.expression.Expression;
|
import net.sf.jsqlparser.expression.Expression;
|
||||||
@ -37,10 +38,7 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
|
|||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
@ -147,13 +145,23 @@ public class PlusDataPermissionHandler {
|
|||||||
if (type == DataScopeType.ALL) {
|
if (type == DataScopeType.ALL) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String sqlTemplate = type.getSqlTemplate();
|
||||||
|
if (type == DataScopeType.CUSTOM_SQL) {
|
||||||
|
//自定义SQL逻辑
|
||||||
|
DataColumn customColum = Arrays.stream(dataColumns).filter(c -> Arrays.asList(c.key()).contains(DataColumn.CUSTOM_SQL)).findFirst().orElseThrow(() -> new ServiceException("角色数据范围异常key配置异常 => " + role.getDataScope()));
|
||||||
|
Map<String, String> map = new HashMap<>();
|
||||||
|
map.put(DataColumn.CUSTOM_SQL, customColum.value()[0]);
|
||||||
|
sqlTemplate = StrUtil.format(sqlTemplate, map);
|
||||||
|
}
|
||||||
|
|
||||||
boolean isSuccess = false;
|
boolean isSuccess = false;
|
||||||
for (DataColumn dataColumn : dataPermission.value()) {
|
for (DataColumn dataColumn : dataPermission.value()) {
|
||||||
if (dataColumn.key().length != dataColumn.value().length) {
|
if (dataColumn.key().length != dataColumn.value().length) {
|
||||||
throw new ServiceException("角色数据范围异常 => key与value长度不匹配");
|
throw new ServiceException("角色数据范围异常 => key与value长度不匹配");
|
||||||
}
|
}
|
||||||
// 不包含 key 变量 则不处理
|
// 不包含 key 变量 则不处理
|
||||||
if (!StringUtils.containsAny(type.getSqlTemplate(),
|
if (!StringUtils.containsAny(sqlTemplate,
|
||||||
Arrays.stream(dataColumn.key()).map(key -> "#" + key).toArray(String[]::new)
|
Arrays.stream(dataColumn.key()).map(key -> "#" + key).toArray(String[]::new)
|
||||||
)) {
|
)) {
|
||||||
continue;
|
continue;
|
||||||
@ -170,7 +178,7 @@ public class PlusDataPermissionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 解析sql模板并填充
|
// 解析sql模板并填充
|
||||||
String sql = parser.parseExpression(type.getSqlTemplate(), parserContext).getValue(context, String.class);
|
String sql = parser.parseExpression(sqlTemplate, parserContext).getValue(context, String.class);
|
||||||
conditions.add(joinStr + sql);
|
conditions.add(joinStr + sql);
|
||||||
isSuccess = true;
|
isSuccess = true;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user