mybatis拦截器实现数据权限

mybatis拦截器实现数据权限

数据权限拦截器:

@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class MyDataPermissionInterceptor extends JsqlParserSupport implements InnerInterceptor {

    /**
     * 数据权限处理器
     */
    private MyDataPermissionHandler dataPermissionHandler;

    @Override
    public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
        if (InterceptorIgnoreHelper.willIgnoreDataPermission(ms.getId())) {
            return;
        }
        PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
        mpBs.sql(this.parserSingle(mpBs.sql(), ms.getId()));
    }

    @Override
    protected void processSelect(Select select, int index, String sql, Object obj) {
        SelectBody selectBody = select.getSelectBody();
        if (selectBody instanceof PlainSelect) {
            this.setWhere((PlainSelect) selectBody, (String) obj);
        } else if (selectBody instanceof SetOperationList) {
            SetOperationList setOperationList = (SetOperationList) selectBody;
            List<SelectBody> selectBodyList = setOperationList.getSelects();
            selectBodyList.forEach(s -> this.setWhere((PlainSelect) s, (String) obj));
        }
    }

    /**
     * 设置 where 条件
     *
     * @param plainSelect  查询对象
     * @param whereSegment 查询条件片段
     */
    private void setWhere(PlainSelect plainSelect, String whereSegment) {

        Expression sqlSegment = this.dataPermissionHandler.getSqlSegment(plainSelect, whereSegment);
        if (null != sqlSegment) {
            plainSelect.setWhere(sqlSegment);
        }
    }
}

具体业务实现拼接

@Slf4j
public class MyDataPermissionHandler {

    private UserService userService;
    /**
     * 获取数据权限 SQL 片段
     *
     * @param plainSelect  查询对象
     * @param whereSegment 查询条件片段
     * @return JSqlParser 条件表达式
     */
    @SneakyThrows(Exception.class)
    public Expression getSqlSegment(PlainSelect plainSelect, String whereSegment) {
        userService = SpringUtils.getBean(UserService.class);
        // 待执行 SQL Where 条件表达式
        Expression where = plainSelect.getWhere();
        if (where == null) {
            where = new HexValue(" 1 = 1 ");
        }
        log.info("开始进行权限过滤,dataFilterMetaData:{} , where: {},mappedStatementId: {}", 111, where, whereSegment);
        //获取mapper名称
        String className = whereSegment.substring(0, whereSegment.lastIndexOf("."));
        //获取方法名
        String methodName = whereSegment.substring(whereSegment.lastIndexOf(".") + 1);
        Table fromItem = (Table) plainSelect.getFromItem();
        // 有别名用别名,无别名用表名,防止字段冲突报错
        Alias fromItemAlias = fromItem.getAlias();
        String mainTableName = fromItemAlias == null ? fromItem.getName() : fromItemAlias.getName();
        //获取当前mapper 的方法
        Method[] methods = Class.forName(className).getMethods();
        for (Method m : methods) {
            if (Objects.equals(m.getName(), methodName)) {
                UserDataPermission annotation = m.getAnnotation(UserDataPermission.class);
                if (annotation == null) {
                    return where;
                }
                Long userId = BaseContextHandler.getUserId();
                User currentUser = userService.getById(userId);
                DataScopeType dsType = currentUser.getDsType();
                //有注解,需要进行数据权限拦截
                switch (dsType) {
                    // 查看全部
                    case ALL:
                        return where;
                    // 查看自己的数据
                    case THIS_LEVEL:
                        //  = 表达式
                        // dept_id = deptId
                        EqualsTo usesEqualsTo = new EqualsTo();
                        usesEqualsTo.setLeftExpression(new Column(mainTableName+".create_user"));
                        usesEqualsTo.setRightExpression(new LongValue(currentUser.getId()));
                        return new AndExpression(where, usesEqualsTo);
                    // 查看本人所在职务以及下属职务
                    case THIS_LEVEL_CHILDREN:
                        //create_user  in (····)
                        // 创建IN 表达式
                        // 创建IN范围的元素集合
                        Long stationId = currentUser.getStationId();
                        List<Long> ids =  userService.getUserAndChildJob(stationId);
                        log.info("本级及子级用户id:{}",ids);
                        // 把集合转变为JSQLParser需要的元素列表
                        ItemsList itemsList = new ExpressionList(ids.stream().map(LongValue::new).collect(Collectors.toList()));
                        InExpression inExpression = new InExpression(new Column(mainTableName+".create_user"), itemsList);
                        return new AndExpression(where, inExpression);
                    // 查看当前部门的数据
                    case THIS_DEPARTMENT:
                        // dept_id = dept_id
                        EqualsTo selfEqualsTo = new EqualsTo();
                        selfEqualsTo.setLeftExpression(new Column(mainTableName+".dept_id"));
                        selfEqualsTo.setRightExpression(new LongValue(currentUser.getOrgId()));
                        return new AndExpression(where, selfEqualsTo);
                    //查看当前部门及下属部门
                    case THIS_DEPARTMENT_CHILDREN:
                        // 创建IN 表达式
                        // 创建IN范围的元素集合
                        Set<Long> deptIds = userService.getDeptIds(currentUser.getOrgId());
                        log.info("本部门及子部门部门id:{}",deptIds);
                        // 把集合转变为JSQLParser需要的元素列表
                        ItemsList deptList = new ExpressionList(deptIds.stream().map(LongValue::new).collect(Collectors.toList()));
                        InExpression inExpressiondept = new InExpression(new Column(mainTableName+".dept_id"), deptList);
                        return new AndExpression(where, inExpressiondept);
                    //本地区
                    case THIS_REGION:
                        // region_id = dept_id
                        EqualsTo regionEqualsTo = new EqualsTo();
                        log.info("查询本地区:{}",currentUser.getAdressId());
                        regionEqualsTo.setLeftExpression(new Column(mainTableName+".region_id"));
                        regionEqualsTo.setRightExpression(new LongValue(currentUser.getAdressId()));
                        return new AndExpression(where, regionEqualsTo);
                    case ASSIGN_USER:
                    case ASSIGN_DEPARTMENT:
                    case ASSIGN_REGION:
                    default:
                        break;
                }
            }

        }
        //说明无权查看,
        where = new HexValue(" 1 = 2 ");
        return where;
    }

}

自定义注解

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserDataPermission {
}

完成拦截器注册

/**
 * @program: crm_backend
 * @description: mybatisplusconfig
 * @author: JiaChaoYang
 * @create: 2022-07-21 17:07
 **/
@Configuration
public class MyBatisPlusConfig {

    /**
     * @Description 分页插件,一缓和二缓遵循mybatis的规则,
     * @Params []
     * @Return com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor
     * @Author JiaChaoYang
     * @Date 2022/7/21 17:10
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 添加数据权限插件
        MyDataPermissionInterceptor dataPermissionInterceptor = new MyDataPermissionInterceptor();
        // 添加自定义的数据权限处理器
        dataPermissionInterceptor.setDataPermissionHandler(new MyDataPermissionHandler());
        interceptor.addInnerInterceptor(dataPermissionInterceptor);
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

如何使用:

在mapper层添加注解即可

    @UserDataPermission
    List<CustomerAllVO> selectAllCustomerPage(IPage<CustomerAllVO> page, @Param("customerName")String customerName ,
                                              @Param("customerCreditCode")String customerCreditCode,
                                              @Param("teamUserId")Integer teamUserId);

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值