El código es demasiado feo, por lo que no se recomienda copiarlo. Puede echar un vistazo a la idea de implementación de RBAC, que es universal.
git clone https://github.com/wjkang/d2-admin-pm.git
npm install
npm start
Requiere soporte del servicio simulado de backend
git clone https://github.com/wjkang/d2-admin-server.git
npm install
npm start
El contenido created
en main.js
se transfiere a router/index.js
y se agrega la lógica relevante.
Se modificó plugin/axios/index.js
del código relacionado con axios para admitir el control de permisos a nivel de interfaz y admitir la configuración de efectos de carga.
Agregue el módulo de menú a la tienda vuex y agregue fullAside , la ruta completa es store.state.d2admin.menu.fullAside
Agregue el módulo de permisos a la tienda vuex para almacenar el código de permiso de función del usuario, el código de rol, la interfaz con permisos de acceso y si el ID del administrador es
export default {
namespaced : true ,
state : {
//功能编码
functions : [ ] ,
//角色编码
roles : [ ] ,
//接口
interfaces : {
GET : [ ] ,
POST : [ ] ,
PUT : [ ] ,
DELETE : [ ]
} ,
//是否管理员
isAdmin : false
} ,
mutations : {
set ( state , data ) {
state . functions = data . functions ;
state . roles = data . roles ;
state . isAdmin = data . isAdmin ;
state . interfaces = data . interfaces ;
}
}
}
Esta parte de load
del módulo account
en la tienda vuex:
// DB -> store 持久化数据加载上次退出时的多页列表
await dispatch ( 'd2admin/page/openedLoad' , null , { root : true } )
Vaya a router/index.js
, debe ejecutarse después de cargar la ruta de permiso.
菜单
y功能
. Puede haber múltiples funciones en un menú. El campo permission
permission
del tipo菜单
identifica los permisos de功能
necesarios para acceder a este menú. el alias de esta función, por lo que菜单
El campo permission
es permission
de un nodo secundario de un tipo功能
.permission
. Utilizando la lógica de inicio de sesión original de d2admin
, el guardia de enrutamiento global determina si se ha extraído la información de permiso y la marca como obtenida una vez obtenida.
La información de permiso que el backend debe devolver incluye el código de función establecido después del filtrado de permisos, el conjunto de códigos de función, el conjunto de información de la interfaz, la lista de menús, la lista de enrutamiento y si se identifica al administrador del sistema. El formato es el siguiente.
{
"statusCode" : 200 ,
"msg" : "" ,
"data" : {
"userName" : "MenuManager" ,
"userRoles" : [
"R_MENUADMIN"
] ,
"userPermissions" : [
"p_menu_view" ,
"p_menu_edit" ,
"p_menu_menu"
] ,
"accessMenus" : [
{
"title" : "系统" ,
"path" : "/system" ,
"icon" : "cogs" ,
"children" : [
{
"title" : "系统设置" ,
"icon" : "cogs" ,
"children" : [
{
"title" : "菜单管理" ,
"path" : "/system/menu" ,
"icon" : "th-list"
}
]
} ,
{
"title" : "组织架构" ,
"icon" : "pie-chart" ,
"children" : [
{
"title" : "部门管理" ,
"icon" : "html5"
} ,
{
"title" : "职位管理" ,
"icon" : "opencart"
}
]
}
]
}
] ,
"accessRoutes" : [
{
"name" : "System" ,
"path" : "/system" ,
"component" : "layoutHeaderAside" ,
"componentPath" : "layout/header-aside/layout" ,
"meta" : {
"title" : "系统设置" ,
"cache" : true
} ,
"children" : [
{
"name" : "MenuPage" ,
"path" : "/system/menu" ,
"component" : "menu" ,
"componentPath" : "pages/sys/menu/index" ,
"meta" : {
"title" : "菜单管理" ,
"cache" : true
}
} ,
{
"name" : "RoutePage" ,
"path" : "/system/route" ,
"component" : "route" ,
"componentPath" : "pages/sys/route/index" ,
"meta" : {
"title" : "路由管理" ,
"cache" : true
}
} ,
{
"name" : "RolePage" ,
"path" : "/system/role" ,
"component" : "role" ,
"componentPath" : "pages/sys/role/index" ,
"meta" : {
"title" : "角色管理" ,
"cache" : true
}
} ,
{
"name" : "UserPage" ,
"path" : "/system/user" ,
"component" : "user" ,
"componentPath" : "pages/sys/user/index" ,
"meta" : {
"title" : "用户管理" ,
"cache" : true
}
} ,
{
"name" : "InterfacePage" ,
"path" : "/system/interface" ,
"component" : "interface" ,
"meta" : {
"title" : "接口管理"
}
}
]
}
] ,
"accessInterfaces" : [
{
"path" : "/menu/:id" ,
"method" : "get"
} ,
{
"path" : "/menu" ,
"method" : "get"
} ,
{
"path" : "/menu/save" ,
"method" : "post"
} ,
{
"path" : "/interface/paged" ,
"method" : "get"
}
] ,
"isAdmin" : 0 ,
"avatarUrl" : "https://api.adorable.io/avatars/85/[email protected]"
}
}
Fusione el menú fijo ( /menu/header
, /menu/aside
) con el menú de permisos ( accessMenus
) devuelto por el backend y guárdelo en el módulo de tienda vuex correspondiente
...
let allMenuAside = [ ... menuAside , ... permissionMenu ]
let allMenuHeader = [ ... menuHeader , ... permissionMenu ]
. . .
// 设置顶栏菜单
store . commit ( 'd2admin/menu/headerSet' , allMenuHeader )
// 设置侧边栏菜单
store . commit ( 'd2admin/menu/fullAsideSet' , allMenuAside )
// 初始化菜单搜索功能
store . commit ( 'd2admin/search/init' , allMenuHeader )
De forma predeterminada, routerMapComponents
se utiliza para procesar las rutas de permiso devueltas por el backend.
//处理动态添加的路由
const formatRoutes = function ( routes ) {
routes . forEach ( route => {
route . component = routerMapComponents [ route . component ]
if ( route . children ) {
formatRoutes ( route . children )
}
} )
}
. . .
formatRoutes ( permissionRouter )
//动态添加路由
router . addRoutes ( permissionRouter ) ;
// 处理路由 得到每一级的路由设置
store . commit ( 'd2admin/page/init' , [ ... frameInRoutes , ... permissionRouter ] )
Para conocer los métodos de procesamiento de enrutamiento y las diferencias, consulte los artículos relacionados más adelante.
Almacene el conjunto de codificación de roles, el conjunto de codificación de funciones, el conjunto de información de la interfaz y si la ID del administrador del sistema está almacenada en el módulo de tienda vuex correspondiente.
...
permission . functions = userPermissionInfo . userPermissions
permission . roles = userPermissionInfo . userRoles
permission . interfaces = util . formatInterfaces ( userPermissionInfo . accessInterfaces )
permission . isAdmin = userPermissionInfo . isAdmin == 1
. . .
// 设置权限信息
store . commit ( 'd2admin/permission/set' , permission )
Admite el control mediante codificación de roles, codificación de funciones y permisos de interfaz, de la siguiente manera
export function getMenuList ( ) {
return request ( {
url : '/menu' ,
method : 'get' ,
interfaceCheck : true ,
permission : [ "p_menu_view" ] ,
loading : {
type : 'loading' ,
options : {
fullscreen : true ,
lock : true ,
text : '加载中...' ,
spinner : 'el-icon-loading' ,
background : 'rgba(0, 0, 0, 0.8)'
}
} ,
success : {
type : 'message' ,
options : {
message : '加载菜单成功' ,
type : 'success'
}
}
} )
}
interfaceCheck: true
significa usar permisos de interfaz para el control. Si la información de la interfaz almacenada en el almacén vuex coincide con la interfaz que se está solicitando actualmente, se puede iniciar la solicitud; de lo contrario, la solicitud será interceptada.
permission:["p_menu_view"]
significa usar codificación de roles y codificación de funciones para la verificación de permisos. Si la codificación de roles o la codificación de funciones almacenada en el almacén vuex coincide con la codificación representada actualmente, se puede iniciar una solicitud; de lo contrario, la solicitud será interceptada.
El código fuente se encuentra en libs/permission.js
y puede modificarse según sus propias necesidades.
El código fuente relacionado con la configuración loading
está en libs/loading.js
libs/loading.js
Puede configurarlo según sus propias necesidades. Lo mismo se aplica al success
. Siguiendo esta idea, puedes configurar otras funciones tú mismo, como solicitud de error, etc.
Utilice la directiva v-permission
:
< el-button
v-permission:function.all =" ['p_menu_edit'] "
type =" primary "
icon =" el-icon-edit "
size =" mini "
@click =" batchEdit "
>批量编辑</ el-button >
El parámetro puede ser function
o role
, lo que indica que la codificación de función o la codificación de rol se usa para la verificación. Si está vacío, ambos se usan para la verificación.
El modificador all
significa que todos los códigos en el valor de la instrucción deben coincidir.
El código fuente se encuentra en plugin/permission/index.js
y puede modificarse según sus necesidades reales.
Utilice el método v-if
+ global:
< el-button
v-if =" canAdd "
type =" primary "
icon =" el-icon-circle-plus-outline "
size =" mini "
@click =" add "
>添加</ el-button >
data ( ) {
return {
canAdd : this . hasPermissions ( [ "p_menu_edit" ] )
} ;
} ,
De forma predeterminada, para la verificación se utilizan tanto la codificación de roles como la codificación de funciones, y solo una de ellas coincide.
Métodos similares también incluyen hasFunctions
y hasRoles
.
El código fuente se encuentra en plugin/permission/index.js
y puede modificarse según sus necesidades reales.
No utilice
v-if="hasPermissions(['p_menu_edit'])"
, lo que hará que el método se ejecute varias veces
También puede leer directamente la información de permisos de la tienda vuex en el componente para su verificación.
Los componentes a nivel de página se colocan en el directorio pages/
y se exportan en forma de clave-valor en routerMapCompnonents/index.js
Los menús fijos que no requieren control de permisos se colocan en menu/aside.js
y menu/header.js
Las rutas que no requieren control de permisos se colocan en frameIn
router/routes.js
Los menús y rutas que requieren control de permisos se agregan a través de la función de administración de la interfaz. Asegúrese de que path
del menú corresponda a path
de la ruta Solo cuando name
de la ruta sea consistente con name
del componente de la página. keep-alive
entra en vigor component
de la ruta está en routerMapCompnonents/index.js
.
Los propios desarrolladores pueden mantener la adición de menús y rutas durante la fase de desarrollo y se puede mantener una lista después de conectarse, la lista se puede entregar a las personas relevantes para su mantenimiento.
Si le resulta problemático y no desea que los menús y las rutas se devuelvan desde el backend, puede mantener un menú y rutas en el frontend (
component
de las rutas todavía usan cadenas, consultemock/permissionMenuAndRouter.js
) y mantener los permisos correspondientes en los menús y rutas Codificación, generalmente utiliza codificación funcional. El backend no necesita devolver información de menú ni de enrutamiento, pero aún se necesita otra información de permisos, como codificación de roles, codificación de funciones, etc. A través de la lista de códigos de función devuelta por el backend, los menús y rutas para los que el usuario tiene permisos se filtran en el frontend. El formato de los menús y rutas filtrados es consistente con el formato devuelto previamente por el backend y luego los menús procesados. y las rutas se utilizan como backend. Simplemente manéjelo de la misma manera que lo devuelve el cliente.
El simulacro de datos utiliza d2-admin-server modificado de lazy-mock. En comparación con otras herramientas, utiliza archivos json para el almacenamiento y no necesita instalar una base de datos. La configuración simple puede generar automáticamente interfaces para agregar, eliminar, modificar y consultar. Para un uso detallado, consulte la documentación de Lazy-Mock.
El backend utiliza middleware para controlar los permisos de acceso, como por ejemplo:
. get ( '/menu' , PermissionCheck ( ) , controllers . menu . getMenuList )
PermissionCheck
utiliza la interfaz de verificación de forma predeterminada para verificar si las API a las que pueden acceder los usuarios coinciden con la API actual. Admite el uso de codificación de funciones y codificación de roles para la verificación PermissionCheck(["p_menu_edit"],["r_menu_admin"],true)
. , Capítulo Un parámetro es el código de función, el segundo es el código de función y el tercero es si se utiliza la interfaz para la verificación.
La generación de código front-end aún está en desarrollo...
Resumen del método de implementación del enrutamiento de permisos de vue Resumen del método de implementación del enrutamiento de permisos de vue 2. Serie de diseño de arquitectura de separación front-end y back-end del sistema de gestión empresarial 1. Modelo de permisos