<font color=#999AAA >

</font>

(文章目录

<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/> 欢迎点赞、关注、留言,收藏及转发,一起学习、交流!