0
点赞
收藏
分享

微信扫一扫

封装、获取系统用户信息、角色及权限控制

<font color=#999AAA >

</font>

@[TOC](文章目录

<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">

前言

<font color=#999AAA >
需要在前端页面就获取用户信息、角色、用户菜单权限,实现对不同角色,不同用户,页面、菜单、方法甚至按钮的权限控制。
</font>

<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">

一、举例需求如下图:

在这里插入图片描述

二、前端ElementUI封装全局

系统用户信息、角色信息、菜单权限信息

data : function() {// data属性
   return {
     menuData : [],// 菜单数据
     isCollapse:false,
     defaultEpeneds : [],// 菜单默认展开
     sysUser : {// 当前用户信息
           id : null,
           username : null,
           image : null,
           realName : null,
      },
      sysRole : {// 当前用户角色
           id : null,
           username : null,
           roleIds : [],
           roleOptions : [],
      },
      getUserInfo : function(func) {// 查看个人信息
         // 获取当前实例
         var _this = this;
         // 请求个人信息
         this.doGetData(_this.baseUrl + _this.getUserInfoUrl, {}, function(r) {
            if (r.success) {
               func(r);// 回调
            } else {
               _this.$message.error("服务器异常!");
            }
         });
      },
      getUserRole : function(func) {// 查看个人角色
         // 获取当前实例
         var _this = this;
         // 请求个人信息
         this.doGetData(_this.baseUrl + _this.getUserRoleUrl, {}, function(r) {
            if (r.success) {
               func(r);// 回调
            } else {
               _this.$message.error("服务器异常!");
            }
         });
      },
      getUserMenu : function() {// 获取我的菜单
        // 获取当前实例
        var _this = this;
        // 获取数据
        _this.doGetData(_this.baseUrl + _this.getUserMenuUrl, {platform : "P"}, function(r) {
            if (r.success) {
                _this.menuData = r.data;
                for (var i = 0; i < _this.menuData.length; i++) {
                    _this.defaultEpeneds.push(_this.menuData[i].id);
                }
            } else {
                _this.$message.error("服务器异常!");
            }
        });
      },
      getUserInfoUrl: "sysUser/getUserInfo.do",// 获取用户信息请求URL
      getUserRoleUrl: "sysUser/getUserRole.do",// 获取用户角色请求URL
      getUserMenuUrl : "sysUser/getUserMenu.do",// 获取用户菜单URL
      .........

mounted : function() {
   // 获取实例对象
   var _this = this;
   // 获取个人信息
   _this.getUserInfo(function(r) {
      _this.sysUser = r.data;
   });
   // 获取个人角色
   _this.getUserRole(function(r) {
      _this.sysRole = r.data;
   });
   // 获取菜单列表
   _this.getUserMenu();
    // 触发Common组件已挂载事件
    _this.commonMounted();
    // 监听窗口大小变化
    window.onresize = function() {
        // 根据高度变化调整容器高度
        _this.containerStyle2.height = (window.innerHeight - 60) + "px";
    }
},    

三、后端获取方法

1.控制器

    /**
     * 查询用户信息
     */
    @RequestMapping("/getUserInfo")
    @ResponseBody
    public Result getUserInfo() {
        try {
            // 查询系统用户
            SysUser user = sysUserService.getSysUser(ShiroUtils.getLoginSysUserId());
            // 返回Page结果集
            return Results.queryOk(dto);
        } catch (Exception e) {
            logger.error("查询系统用户信息失败!SysUserId:" + ShiroUtils.getLoginSysUserId(), e);
            return Results.queryError();
        }
    }

    /**
     * @Description 获取用户角色
     **/
    @RequestMapping("/getUserRole")
    @ResponseBody
    public Result getUserRole() {
        try {
            // 查询系统用户
            SysUserRoles userRoles= sysUserService.getSysUserRoles(ShiroUtils.getLoginSysUserId());
            return Results.queryOk(dto);
        } catch (Exception e) {
            logger.error("查询系统用户角色信息失败!SysUserId:" + ShiroUtils.getLoginSysUserId(), e);
            return Results.queryError();
        }
    }

    /**
     * 获取用户菜单
     */
    @SuppressWarnings("unchecked")
    @RequestMapping("/getUserMenu")
    @ResponseBody
    public Result getUserMenu(@Valid GetUserMenuParam params, BindingResult r) {
        try {
            if (r.hasErrors()) {
                return Results.paramError(r);
            }
            // 获取菜单会话属性
            Object obj = ShiroUtils.getSessionAttr(Constants.USER_MENU_KEY);
            List<SysUserMenuItem> menus = null;
            if (obj == null) {// 没有会话属性
                // 从数据库加载
                menus = sysUserService.getUserMenuItems(params.getPlatform());
                String menusJson = JSON.toJSONString(menus);
                // 设置会话属性
                ShiroUtils.setSessionAttr(Constants.USER_MENU_KEY, menusJson);
            } else {
                // 有会话属性,直接使用会话属性
                 menus =JSON.parseArray((String)obj, SysUserMenuItemDto.class);
            }
            return Results.listResult(menus);
        } catch (Exception e) {
            logger.error("获取我的菜单失败!params:" + params.toString(), e);
            return Results.opError();
        }
    }
2.实现接口

    /**
     * 获取用户信息
     */
    @Override
    public SysUser getSysUser(String userId) {
        SysUser sysUser = sysUserService.selectById(userId);
        return sysUser ;
    }

    /**
     * 获取用户角色
     */
    @Override
    public SysUserRoles getSysUserRoles(String userId) {
        // 创建响应对象
        SysUserRoles dto = new SysUserRoles();
        // 查询系统用户信息
        SysUser sysUser = sysUserService.selectById(sysUserId);
        BeanUtils.copyProperties(sysUser, dto);
        // 查询指定系统用户的角色信息列表
        List<SysUserRole> list = sysUserRoleService.selectList(SQLHelper.build(SysUserRole.class)
                        .eq("userId", userId).geEntityWrapper());
        // 提取系统用户的角色ID列表            
        List<String> roleIds = list.stream().map(SysUserRole::getRoleId).collect(toList());
        dto.setRoleIds(roleIds);
        // 查询所有角色选项
        List<Role> roles = roleService.selectList(SQLHelper.build(Role.class).geEntityWrapper());
        List<OptionDto> roleOptions = roles.stream().map(r -> {
            OptionDto option = new OptionDto();
            option.setDisabled(false);
            option.setValue(r.getId());
            option.setLabel(r.getName());
            return option;
        }).collect(toList());
        dto.setRoleOptions(roleOptions);
        return dto;
    }

    /**
     * 获取用户菜单权限
     */
    @SuppressWarnings("unchecked")
    @Override
    public List<SysUserMenuItem> getUserMenuItems(String platform) {
        // 查询指定用户的角色ID列表
        List<SysUserRole> list = sysUserRoleService.selectList(SQLHelper.build(SysUserRole.class)
                        .eq("sysUserId", ShiroUtils.getLoginSysUserId()).geEntityWrapper(););
        // 提取系统用户的角色ID列表
        List<String> roleIds = list.stream().map(SysUserRole::getRoleId).collect(toList());
        // 查询当前系统用户所有角色合并的权限信息
        List<String> permissionIds = rolePermissionService.selectList(// 查询角色权限关系列表
                SQLHelper.build(RolePermission.class).in("roleId", roleIds).geEntityWrapper()).parallelStream()// 开始流处理
                .map(RolePermission::getPermissionId)// 提取权限ID
                .distinct()// 对权限ID去重
                .collect(toList());// 收集权限ID
        // 查询当前用户的所有权限信息列表
        List<Permission> permissions = permissionService.selectBatchIds(permissionIds);
        // 转换
        List<SysUserMenuItem> dtos = permissions.parallelStream()// 开始并行流处理
                .filter(p -> p.isMenu() && p.getPlatform().equals(platform))// 过滤出菜单权限和特定平台权限
                .sequential()// 开始顺序流处理
                .sorted((p1, p2) -> p1.getOrder().compareTo(p2.getOrder()))// 按Order进行排序
                .map(p -> {
                    // 转换为DTO
                    SysUserMenuItem dto = new SysUserMenuItem();
                    BeanUtils.copyProperties(p, dto);
                    dto.setId(p.getUrl() == null ? p.getId() : p.getUrl());
                    return dto;
                }).collect(toList());// 收集
        // 转换为树结构
        return (List<SysUserMenuItem>) TreeUtils.toTree(dtos);
    }
3.ShiroUtils工具类

项目采用shiro权限控制

package com.cherry.framework.shiro.utils;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;

import com.cherry.shop.security.entity.SysUser;
import com.cherry.shop.user.entity.User;

/**
 * Shiro工具类
 */
public class ShiroUtils {

    /**
     * 获取凭证
     * @param clazz
     * 凭证字节码对象
     * @return 凭证
     */
    @SuppressWarnings("unchecked")
    public static <T> T getPrincipal(Class<T> clazz) {
        return (T) SecurityUtils.getSubject().getPrincipal();
    }

    /**
     * 获取当前登录的系统用户
     * @return 当前登录的系统用户
     */
    public static SysUser getLoginSysUserId() {
        return getPrincipal(SysUser.class);
    }

    /**
     * 获取当前系统用户ID
     * @return 当前系统用户ID
     */
    public static String getLoginSysUserId() {
        return getLoginSysUser().getId();
    }

    /**
     * 获取当前登录的系统用户
     * @return 当前登录的系统用户
     */
    public static SysUser getLoginSysUser() {
        return getPrincipal(SysUser.class);
    }

    /**
     * 设置会话属性
     * @param key 键
     * @param value 值
     */
    public static void setSessionAttr(String key, Object value) {
        SecurityUtils.getSubject().getSession().setAttribute(key, value);
    }

    /**
     * 获取会话属性
     * @param key 键
     * @return 值
     */
    public static Object getSessionAttr(String key) {
        return SecurityUtils.getSubject().getSession().getAttribute(key);
    }

}

四、前端页面引用全局方法


    // 开票按钮
    <el-button size="mini" type="text" icon="icon iconfont icon-jihuopeizhi" @click="handleSetInvoice(scope.row)" v-if="scope.row.isInvoice == '0'"  :disabled="setInvoiceVisible" >开票 </el-button>

...............................

      // 查询企业列表方法(开票按钮是在查询出来的企业才能操作)
      handleQuery: function (event) {
        // 直接调用页面全局变量sysRole的角色roleIds
          var roleIds = this.sysRole.roleIds;
          for(var i=0;i<roleIds.length;i++){
              var roleId = roleIds[i];
              if(roleId != undefined && roleId != null && roleId != ""){
                // 如果角色roleId中包括1,则设置按钮不禁用 -- 即有开票权限
                  if(roleId == 1 ){
                      this.setInvoiceVisible = false;
                      break;
                  }
              }
          }
          // 这个是调用查询企业列表方法
          this.refreshData();
      }

<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">

随心所往,看见未来。Follow your heart,see night!<br/>
欢迎点赞、关注、留言,收藏及转发,一起学习、交流!

举报

相关推荐

0 条评论