Le code est trop moche, il n'est donc pas recommandé de le copier. Vous pouvez jeter un œil à l'idée d'implémentation de RBAC, qui est universelle.
git clone https://github.com/wjkang/d2-admin-pm.git
npm install
npm start
Nécessite la prise en charge du service simulé backend
git clone https://github.com/wjkang/d2-admin-server.git
npm install
npm start
Le contenu created
dans main.js
est transféré vers router/index.js
et la logique pertinente est ajoutée.
Modification plugin/axios/index.js
de code lié à axios pour prendre en charge le contrôle des autorisations au niveau de l'interface et prendre en charge la configuration des effets de chargement.
Ajoutez le module de menu au magasin vuex et ajoutez fullAside , le chemin complet est store.state.d2admin.menu.fullAside
Ajoutez le module d'autorisation au magasin vuex pour stocker le code d'autorisation de fonction de l'utilisateur, le code de rôle, l'interface avec les autorisations d'accès et si l'ID d'administrateur est
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 ;
}
}
}
Cette partie de load
du module account
dans le magasin vuex :
// DB -> store 持久化数据加载上次退出时的多页列表
await dispatch ( 'd2admin/page/openedLoad' , null , { root : true } )
Accédez à router/index.js
, il doit être exécuté après avoir chargé la route d'autorisation.
菜单
et功能
. Il peut y avoir plusieurs fonctions sous un menu. Le champ permission
permission
du type菜单
identifie les autorisations de功能
requises pour accéder à ce menu. l'alias de cette fonction, donc菜单
. Le champ permission
est permission
d'un nœud enfant d'un type功能
.permission
. En utilisant la logique de connexion d'origine de d2admin
, le garde de routage global détermine si les informations d'autorisation ont été extraites et les marque comme obtenues après leur obtention.
Les informations d'autorisation que le backend doit renvoyer incluent le code de rôle défini après le filtrage des autorisations, le jeu de codes de fonction, le jeu d'informations d'interface, la liste de menus, la liste de routage et si l'administrateur système est identifié. Le format est le suivant
{
"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]"
}
}
Fusionnez le menu fixe ( /menu/header
, /menu/aside
) avec le menu d'autorisation ( accessMenus
) renvoyé par le backend et stockez-le dans le module de magasin vuex correspondant
...
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 )
Par défaut, routerMapComponents
est utilisé pour traiter les routes d'autorisation renvoyées par le 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 ] )
Pour connaître les méthodes de traitement du routage et les différences, veuillez consulter les articles associés ultérieurement.
Stockez l'ensemble de codes de rôle, l'ensemble de codes de fonction, l'ensemble d'informations d'interface et si l'ID de l'administrateur système est stocké dans le module de magasin Vuex correspondant
...
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 )
Prend en charge le contrôle à l'aide du codage de rôle, du codage de fonction et des autorisations d'interface, comme suit
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
signifie utiliser les autorisations d'interface pour le contrôle. Si les informations d'interface stockées dans le magasin vuex correspondent à l'interface actuellement demandée, la demande peut être lancée, sinon la demande sera interceptée.
permission:["p_menu_view"]
signifie utiliser le codage de rôle et le codage de fonction pour la vérification des autorisations. Si le codage de rôle ou le codage de fonction stocké dans le magasin vuex correspond au codage actuellement représenté, une demande peut être lancée, sinon la demande sera interceptée.
Le code source se trouve dans libs/permission.js
et peut être modifié selon vos propres besoins.
Le code source lié à la configuration loading
est dans libs/loading.js
libs/loading.js
Vous pouvez le configurer selon vos propres besoins. Il en va de même pour success
. En suivant cette idée, vous pouvez configurer vous-même d'autres fonctions, comme l'échec de la demande, etc.
Utilisez la directive v-permission
:
< el-button
v-permission:function.all =" ['p_menu_edit'] "
type =" primary "
icon =" el-icon-edit "
size =" mini "
@click =" batchEdit "
>批量编辑</ el-button >
Le paramètre peut être function
ou role
, indiquant que le codage de fonction ou le codage de rôle est utilisé pour la vérification. S'il est vide, les deux sont utilisés pour la vérification.
Le modificateur all
signifie que tous les codes de la valeur de l’instruction doivent correspondre.
Le code source se trouve dans plugin/permission/index.js
et peut être modifié selon vos besoins réels.
Utilisez la méthode v-if
+ globale :
< 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" ] )
} ;
} ,
Par défaut, le codage de rôle et le codage de fonction sont utilisés pour la vérification, et un seul d'entre eux correspond.
Des méthodes similaires incluent également hasFunctions
et hasRoles
.
Le code source se trouve dans plugin/permission/index.js
et peut être modifié selon vos besoins réels.
N'utilisez pas
v-if="hasPermissions(['p_menu_edit'])"
, ce qui entraînerait l'exécution de la méthode plusieurs fois.
Vous pouvez également lire directement les informations d'autorisation du magasin vuex dans le composant pour vérification.
Les composants au niveau de la page sont placés dans le répertoire pages/
et exportés sous forme de clé-valeur dans routerMapCompnonents/index.js
Les menus fixes qui ne nécessitent pas de contrôle d'autorisation sont placés dans menu/aside.js
et menu/header.js
Les routes qui ne nécessitent pas de contrôle d'autorisation sont placées dans router/routes.js
frameIn
Les menus et les itinéraires qui nécessitent un contrôle d'autorisation sont ajoutés via la fonction de gestion de l'interface. Assurez-vous que path
du menu correspond au path
de l'itinéraire. Uniquement lorsque name
de l'itinéraire est cohérent avec name
du composant de la page. keep-alive
prend effet. component
de la route est dans routerMapCompnonents/index.js
.
L'ajout de menus et d'itinéraires pendant la phase de développement peut être géré par les développeurs eux-mêmes et une liste peut être maintenue après la mise en ligne, la liste peut être transmise aux personnes concernées pour maintenance.
Si vous trouvez cela gênant et ne souhaitez pas que les menus et les routes soient renvoyés depuis le backend, vous pouvez conserver un menu et des routes sur le frontend (
component
des routes utilisent toujours des chaînes, reportez-vous àmock/permissionMenuAndRouter.js
) et maintenir les autorisations correspondantes sur les menus et les itinéraires. Le codage, utilise généralement un codage fonctionnel. Le backend n'a pas besoin de renvoyer les informations de menu et de routage, mais d'autres informations d'autorisation, telles que le codage de rôle, le codage de fonction, etc., sont toujours nécessaires. Grâce à la liste de codes de fonction renvoyée par le backend, les menus et les itinéraires pour lesquels l'utilisateur dispose d'autorisations sont filtrés sur le frontend. Le format des menus et des itinéraires filtrés est cohérent avec le format précédemment renvoyé par le backend, puis les menus traités. et les routes sont utilisées comme backend. Il suffit de les gérer de la même manière que ce qui est renvoyé par le client.
Data mock utilise d2-admin-server modifié à partir de lazy-mock. Par rapport à d'autres outils, il prend en charge la persistance des données et n'a pas besoin d'installer de base de données. Une configuration simple peut générer automatiquement des interfaces pour l'ajout, la suppression, la modification et la requête. Pour une utilisation détaillée, veuillez consulter la documentation lazy-mock.
Le backend utilise un middleware pour contrôler les autorisations d'accès, telles que :
. get ( '/menu' , PermissionCheck ( ) , controllers . menu . getMenuList )
PermissionCheck
utilise l'interface de vérification par défaut pour vérifier si les API accessibles aux utilisateurs correspondent à l'API actuelle. Elle prend en charge l'utilisation du codage de fonction et du codage de rôle pour la vérification. PermissionCheck(["p_menu_edit"],["r_menu_admin"],true)
, Le premier paramètre du chapitre est le code de fonction, le deuxième est le code de rôle et le troisième est de savoir s'il faut utiliser l'interface pour la vérification.
La génération de code front-end est encore en cours de développement...
Résumé de la méthode de mise en œuvre du routage des autorisations vue Résumé de la méthode de mise en œuvre du routage des autorisations vue 2. Série de conceptions d'architecture de séparation frontale et back-end du système de gestion d'entreprise 1. Modèle d'autorisation