vue-admin-template添加页面权限

1,006 阅读4分钟

一、先建立数据库表

1、ucenter_member用户表

-- auto-generated definition
create table ucenter_member
(
    id           char(19) charset utf8mb4               not null comment '会员id'
        primary key,
    avatar       varchar(255) charset utf8mb4           null comment '用户头像',
    mobile       varchar(11) charset utf8mb4 default '' null comment '手机号',
    rel_name     varchar(50)                            not null comment '真实姓名',
    nickname     varchar(50) charset utf8mb4            not null comment '昵称(学号)',
    password     varchar(255) charset utf8mb4           null comment '密码',
    department   varchar(128)                           null comment '系别',
    grade        varchar(10)                            null comment '年级',
    sex          tinyint(2) unsigned                    null comment '性别 1 女,2 男',
    age          tinyint unsigned                       null comment '年龄',
    is_deleted   tinyint(1)                  default 0  not null comment '逻辑删除 1(true)已删除, 0(false)未删除',
    is_disabled  tinyint(1)                  default 0  not null comment '是否禁用 1(true)已禁用,  0(false)未禁用',
    gmt_create   datetime                               not null comment '创建时间',
    gmt_modified datetime                               not null comment '更新时间'
);

2、ucenter_role角色表

-- auto-generated definition
create table ucenter_role
(
    id           char(19)            default '' not null comment '角色id'
        primary key,
    role_name    varchar(20)         default '' not null comment '角色名称',
    role_code    varchar(20)                    null comment '角色编码',
    remark       varchar(255)                   null comment '备注',
    is_deleted   tinyint(1) unsigned default 0  not null comment '逻辑删除 1(true)已删除, 0(false)未删除',
    gmt_create   datetime                       not null comment '创建时间',
    gmt_modified datetime                       not null comment '更新时间'
);

3、ucenter_permission权限表

-- auto-generated definition
create table ucenter_permission
(
    id               char(19) charset utf8mb4    default '' not null comment '编号'
        primary key,
    pid              char(19) charset utf8mb4    default '' not null comment '所属上级',
    name             varchar(20) charset utf8mb4 default '' not null comment '名称',
    type             tinyint(3)                  default 0  not null comment '类型(1:菜单,2:按钮)',
    permission_value varchar(50) charset utf8mb4            null comment '权限值',
    path             varchar(100) charset utf8mb4           null comment '访问路径',
    component        varchar(100) charset utf8mb4           null comment '组件路径',
    icon             varchar(50) charset utf8mb4            null comment '图标',
    status           tinyint                                null comment '状态(0:禁止,1:正常)',
    is_deleted       tinyint(1) unsigned         default 0  not null comment '逻辑删除 1(true)已删除, 0(false)未删除',
    gmt_create       datetime                               null comment '创建时间',
    gmt_modified     datetime                               null comment '更新时间'
);

4、ucenter_member_role用户角色的中间表

-- auto-generated definition
create table ucenter_member_role
(
    id           char(19)            default ''  not null comment '主键id'
        primary key,
    role_id      char(19)            default '0' not null comment '角色id',
    user_id      char(19)            default '0' not null comment '用户id',
    is_deleted   tinyint(1) unsigned default 0   not null comment '逻辑删除 1(true)已删除, 0(false)未删除',
    gmt_create   datetime                        not null comment '创建时间',
    gmt_modified datetime                        not null comment '更新时间'
);

5、ucenter_role_permission角色权限的中间表

-- auto-generated definition
create table ucenter_role_permission
(
    id            char(19)            default '' not null
        primary key,
    role_id       char(19)            default '' not null,
    permission_id char(19)            default '' not null,
    is_deleted    tinyint(1) unsigned default 0  not null comment '逻辑删除 1(true)已删除, 0(false)未删除',
    gmt_create    datetime                       not null comment '创建时间',
    gmt_modified  datetime                       not null comment '更新时间'
);

二、获取用户的权限

1、根据用户id查询得到 List<Permission

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sise.wangzhan.ucenter.mapper.PermissionMapper">
    <resultMap id="permissionMap" type="com.sise.wangzhan.ucenter.entity.Permission">
        <result property="id" column="id"/>
        <result property="pid" column="pid"/>
        <result property="name" column="name"/>
        <result property="type" column="type"/>
        <result property="permissionValue" column="permission_value"/>
        <result property="path" column="path"/>
        <result property="component" column="component"/>
        <result property="icon" column="icon"/>
        <result property="status" column="status"/>
        <result property="isDeleted" column="is_deleted"/>
        <result property="gmtCreate" column="gmt_create"/>
        <result property="gmtModified" column="gmt_modified"/>
    </resultMap>

    <!-- 用于select查询公用抽取的列 -->
    <sql id="columns">
        up.id,up.pid,up.name,up.type,up.permission_value,up.path,up.component,up.icon,up.status,up.is_deleted,up.gmt_create,up.gmt_modified
    </sql>

    <select id="selectPermissionByUserId" resultMap="permissionMap">
        select
        <include refid="columns" />
        from ucenter_member_role umr
        inner join ucenter_role_permission urp on umr.role_id = urp.role_id
        inner join ucenter_permission up on urp.permission_id = up.id
        where umr.user_id = #{userId}
        and umr.is_deleted = 0
        and urp.is_deleted = 0
        and up.is_deleted = 0
    </select>
</mapper>

2、修改实体类

3、根据权限数据构建菜单数据

package com.sise.wangzhan.ucenter.helper;

import com.sise.wangzhan.ucenter.entity.Permission;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 根据权限数据构建菜单数据
 * </p>
 *
 * @author qy
 * @since 2019-11-11
 */
public class PermissionHelper {

    /**
     * 使用递归方法建菜单
     * @param treeNodes
     * @return
     */
    public static List<Permission> bulid(List<Permission> treeNodes) {
        List<Permission> trees = new ArrayList<>();
        for (Permission treeNode : treeNodes) {
            if ("0".equals(treeNode.getPid())) {
                treeNode.setLevel(1);
                trees.add(findChildren(treeNode,treeNodes));
            }
        }
        return trees;
    }

    /**
     * 递归查找子节点
     * @param treeNodes
     * @return
     */
    public static Permission findChildren(Permission treeNode,List<Permission> treeNodes) {
        treeNode.setChildren(new ArrayList<Permission>());

        for (Permission it : treeNodes) {
            if(treeNode.getId().equals(it.getPid())) {
                int level = treeNode.getLevel() + 1;
                it.setLevel(level);
                if (treeNode.getChildren() == null) {
                    treeNode.setChildren(new ArrayList<>());
                }

                treeNode.getChildren().add(findChildren(it,treeNodes));
            }
        }
        return treeNode;
    }
}

4、构建菜单

package com.sise.wangzhan.ucenter.helper;

import com.alibaba.fastjson.JSONObject;
import com.sise.wangzhan.ucenter.entity.Permission;
import org.springframework.boot.configurationprocessor.json.JSONException;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 根据权限数据构建登录用户左侧菜单数据
 * </p>
 *
 * @author qy
 * @since 2019-11-11
 */
public class MemuHelper {

    /**
     * 构建菜单
     * @param treeNodes
     * @return
     */
    public static List<JSONObject> bulid(List<Permission> treeNodes) throws JSONException {
        List<JSONObject> meuns = new ArrayList<>();
        if(treeNodes.size() == 1) {
            Permission topNode = treeNodes.get(0);
            //左侧一级菜单
            List<Permission> oneMeunList = topNode.getChildren();

            for(Permission one :oneMeunList) {

                JSONObject oneMeun = new JSONObject();
                oneMeun.put("path", one.getPath());
                oneMeun.put("component", "Layout");
                oneMeun.put("redirect", one.getComponent());
                oneMeun.put("name", "name_"+one.getId());
                oneMeun.put("hidden", false);

                JSONObject oneMeta = new JSONObject();
                oneMeta.put("title", one.getName());
                oneMeta.put("icon", one.getIcon());
                oneMeun.put("meta", oneMeta);

                List<JSONObject> children = new ArrayList<>();
                List<Permission> twoMeunList = one.getChildren();
                for(Permission two :twoMeunList) {
                    JSONObject twoMeun = new JSONObject();
                    twoMeun.put("path", two.getPath());
                    twoMeun.put("component", two.getComponent());
                    twoMeun.put("name", "name_"+two.getId());
                    twoMeun.put("hidden", false);

                    JSONObject twoMeta = new JSONObject();
                    twoMeta.put("title", two.getName());
                    twoMeun.put("meta", twoMeta);

                    children.add(twoMeun);

                    List<Permission> threeMeunList = two.getChildren();
                    for(Permission three :threeMeunList) {
                        if(StringUtils.isEmpty(three.getPath())) continue;

                        JSONObject threeMeun = new JSONObject();
                        threeMeun.put("path", three.getPath());
                        threeMeun.put("component", three.getComponent());
                        threeMeun.put("name", "name_"+three.getId());
                        threeMeun.put("hidden", true);

                        JSONObject threeMeta = new JSONObject();
                        threeMeta.put("title", three.getName());
                        threeMeun.put("meta", threeMeta);

                        children.add(threeMeun);
                    }
                }
                oneMeun.put("children", children);
                meuns.add(oneMeun);
            }
        }
        return meuns;
    }
}

5、构建的大概菜单

{
	"redirect": "/ucenter/ucenterList",
	"path": "/ucenter",
	"component": "Layout",
	"hidden": false,
	"children": [{
		"path": "/ucenterList",
		"component": "/ucenter/ucenterList",
		"hidden": false,
		"meta": {
			"title": "查看用户"
		},
		"name": "name_3333"
	}, {
		"path": "/ucenterSave",
		"component": "/ucenter/ucenterSave",
		"hidden": false,
		"meta": {
			"title": "添加用户"
		},
		"name": "name_3333333"
	}],
	"meta": {
		"icon": "example",
		"title": "用户管理"
	},
	"name": "name_222"
}, {
	"redirect": "/course/courseList",
	"path": "/course",
	"component": "Layout",
	"hidden": false,
	"children": [{
		"path": "/courseList",
		"component": "/course/courseList",
		"hidden": false,
		"meta": {
			"title": "查看课程"
		},
		"name": "name_555"
	}, {
		"path": "/courseSave",
		"component": "/course/courseSave",
		"hidden": false,
		"meta": {
			"title": "添加课程"
		},
		"name": "name_666"
	}, {
		"path": "/courseUpdate",
		"component": "/course/courseUpdate",
		"hidden": false,
		"meta": {
			"title": "修改课程"
		},
		"name": "name_777"
	}],
	"meta": {
		"icon": "example",
		"title": "课程管理"
	},
	"name": "name_444"
}

三、前端接收

1、接收前先建立对应的文件

2、动态添加路由


2.1、在getters.js中添加

2.2、遍历后台传来的路由字符串,转换为组件对象(在store下的module添加)

/*
 * @Author: your name
 * @Date: 2021-01-19 11:05:28
 * @LastEditTime: 2021-01-19 11:19:51
 * @LastEditors: your name
 * @Description: In User Settings Edit
 * @FilePath: \vue-admin-template-master\src\store\modules\permission.js
 */
import { constantRoutes } from '@/router'
import { getMenu } from '@/api/login'
import Layout from '@/views/layout/Layout'

function filterAsyncRouter(asyncRouterMap) { // 遍历后台传来的路由字符串,转换为组件对象
  try {
    const accessedRouters = asyncRouterMap.filter(route => {
      if (route.component) {
        if (route.component === 'Layout') { // Layout组件特殊处理
          route.component = Layout
        } else {
          const component = route.component
          route.component = resolve => {
            require(['@/views' + component + '.vue'], resolve)
          }
        }
      }
      if (route.children && route.children.length) {
        route.children = filterAsyncRouter(route.children)
      }
      return true
    })
    return accessedRouters
  } catch (e) {
    console.log(e)
  }
}

const state = {
  routes: [],
  addRoutes: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
}

const actions = {
  async generateRoutes({ commit }) {
    // 取后台路由

    const asyncRouter = await getMenu()

    return new Promise(resolve => {
      const tmp = asyncRouter.data.permissionList
      const accessedRoutes = filterAsyncRouter(tmp)

      commit('SET_ROUTES', accessedRoutes)
      resolve(accessedRoutes)
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

2.3、添加动态路由

3、解决刷新vuex状态丢失问题

四、成功后截图

1、admin管理员有所有的权限

2、普通用户权限