数据权限

第一次写数据权限,在网上找了很多材料,不知道具体功能能不能实现,姑且试试

背景

  • 主要显示表,园区表,大棚表,用户表,权限表。
  • 权限分为5种:1、所有权限;2、自定义权限(暂无用处,先设计上);3、园区及以下权限;4、大棚权限;5、个人。(注:2、5没用上,姑且就这样吧)

设计

1.设计注解(还算一个小白,对注解不是很熟悉)
//注解的作用目标
@Target(ElementType.METHOD)
//注解的生命周期
@Retention(RetentionPolicy.RUNTIME)
//用来做标识(个人认为意义不大)
@Documented
public @interface WechatDataScope {

    /**
     * 园区表的别名
     * @return
     */
    public String parkAlias() default "";

    /**
     * 大棚表名
     * @return
     */
    public String greenhouseAlias() default "";
}
2.创建切面(第一次写切面)
/**
 * 数据切面
 *
 * @author zhangxq
 * @version 0.1
 * @Time 3/25
 */
@Aspect
// 基础注解之一:为spring容器注册Bean
@Component
public class WechatDataScopeAspect {

    // 1. 定义静态属性(权限)
    // 权限1:全部
    private static final String WECHAT_DATA_SCOPE_ALL = "1";
    // 权限1:自定义
    private static final String WECHAT_DATA_SCOPE_CUSTOM = "2";
    // 权限1:园区
    private static final String WECHAT_DATA_SCOPE_PARK = "3";
    // 权限1:大棚
    private static final String WECHAT_DATA_SCOPE_GREENHOUSE = "4";
    // 权限1:本人
    private static final String WECHAT_DATA_SCOPE_SELF = "5";

    // 2. 定义数据权限过滤的关键字

    private static final String WECHAT_DATA_SCOPE = "wechatDataScope";

    // 3. 编辑织入点,空方法体
    @Pointcut("@annotation(com.joolun.common.annotation.WechatDataScope)")
    public void wechatDataScopePointCut(){
    }

    // 4. 增强类型,此处需要用到前置通知,去判断权限
    @Before("wechatDataScopePointCut()")
    public void doBefore(JoinPoint joinPoint) throws Throwable{
        handleDataScope(joinPoint);
    }

    public void handleDataScope(final JoinPoint joinPoint){

        // 获取注解,先去定义获取注解的方法,见方法getAnnotation
        WechatDataScope wechatDataScope = getAnnotation(joinPoint);
        if (wechatDataScope == null){
            return;
        }
        //获取用户权限(我是因为登录没有用Secriuty框架,查询的时候前台传的权限的信息)
        WechatLoginInfo wechatLoginInfo = (WechatLoginInfo)joinPoint.getArgs()[0];
        // 判断如果用户存在
        if (wechatLoginInfo != null){
            dataScopeFilter(joinPoint,wechatLoginInfo,wechatDataScope.parkAlias(),wechatDataScope.greenhouseAlias());
        }
    }

    /**
     * 数据过滤
     * @param joinPoint
     * @param user
     * @param parkAlias
     * @param greenhouseAlias
     */
    public static void dataScopeFilter(JoinPoint joinPoint, WechatLoginInfo user, String parkAlias, String greenhouseAlias)
    {

        StringBuilder sqlString = new StringBuilder();
        String dataScope = user.getDataScope();
        // 因为我获取园区和大棚两个是分开查的,懒得再写一个了,在这加个判断算了(如果有更好的方法可以告诉我)
        if (joinPoint.getSignature().getName().equals("getPark")) {
            if (WECHAT_DATA_SCOPE_ALL.equals(dataScope)) {
                sqlString = new StringBuilder();
                // 自定义
            } else if (WECHAT_DATA_SCOPE_CUSTOM.equals(dataScope)) {
                //拼接sql
                sqlString.append(StringUtils.format("where {}.id in (select dept_id from sys_role_dept where role_id = {})"
                        , greenhouseAlias, user.getRoleId()));
                //  权限3.园区及以下
            } else if (WECHAT_DATA_SCOPE_PARK.equals(dataScope)) {
                sqlString.append(StringUtils.format("Left Join sys_user su on (su.ssYqDp = {}.id) WHERE su.user_name = {}"
                    ,parkAlias,user.getUserName()));
                // 权限4.大棚
            } else if (WECHAT_DATA_SCOPE_GREENHOUSE.equals(dataScope)) {
                sqlString.append(StringUtils.format("Left Join sys_user su on (su.ssYqDp = {}.id) WHERE su.user_name = {}"
                        ,greenhouseAlias,user.getUserName()));
                // 权限5.本人
            } else if (WECHAT_DATA_SCOPE_SELF.equals(dataScope)) {
                sqlString.append(StringUtils.format("WHERE {}.createUser = {} or {}.createUser = {}"
                        ,parkAlias,user.getUserName(),greenhouseAlias,user.getUserName()));
            }
            // 大棚
        }else if(joinPoint.getSignature().getName().equals("getGreenhouse")){
            // 如果是自定义
            if (WECHAT_DATA_SCOPE_CUSTOM.equals(dataScope)){
                sqlString.append(StringUtils.format("AND {}.id in (select dept_id from sys_role_dept where role_id = {})",
                        greenhouseAlias,user.getRoleId()));
            }else if (WECHAT_DATA_SCOPE_GREENHOUSE.equals(dataScope)){
                sqlString.append(StringUtils.format("AND {}.id = (select ssYqDp from sys_user where user_name = {})",
                        greenhouseAlias,user.getUserName()));
            }else if (WECHAT_DATA_SCOPE_SELF.equals(dataScope)){
                sqlString.append(StringUtils.format("AND {}.createUser = {}",
                        greenhouseAlias,user.getUserName()));
            }else{
                sqlString = new StringBuilder();
            }
        }
        //判断是不是空,将数据权限的sql放到实体类里
        if (StringUtils.isNotBlank(sqlString.toString())){
            Object params = joinPoint.getArgs()[0];
            // 用来判断能否携带参数
            if (StringUtils.isNotNull(params) && params instanceof BaseEntity){
                BaseEntity baseEntity = (BaseEntity) params;
                baseEntity.getParams().put(WECHAT_DATA_SCOPE,sqlString);
            }
        }

    }
    /**
     * 是否存在注解,有就获取注解
     * @param joinPoint
     * @return
     */
    public WechatDataScope getAnnotation(JoinPoint joinPoint){
        // 获取被增强的相关信息
        Signature signature = joinPoint.getSignature();
        // 因为作用在方法上,所以强转为被增强的方法的相关信息(个人这样理解)
        MethodSignature methodSignature = (MethodSignature) signature;
        // 获取方法
        Method method = methodSignature.getMethod();
        // 如果存在该方法
        if (method != null){
            // 返回方法上的注解
            return method.getAnnotation(WechatDataScope.class);
        }
        return null;
    }
}
3.掌握的技术
  • AOP:面向切面编程(一直在背,接触不多)
    • 创建接口注解
    • 定义织入点(空方法体)
    • 增强类型(注解具体要干什么在这里写)类型分为前置,后置,环绕,报错后置,引介增强
4.个人提醒(大佬就不要看了)
  • 对于数据权限而言,注解接口里属性只用表的别名,当你用注解的时候,一定要注意,你定义表的别名和你xml里边sql表的别名一定要一致。
  • 因为我没有用Secriuty框架,所以我自己前台获取的个人相关信息,用Secriuty的可以用
LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest());

以上都是自己个人看法,还有很多东西没有触及,真的是知道的越多,不知道的越多。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值