為了進一步實現上面提到的動態路由功能,并且加入對每個路由的權限控制(即增、刪、改、查按鈕的權限控制),我們需要對數據庫、后端接口、前端的設計做一些改進和擴展。下面我將詳細描述如何在現有方案的基礎上加入對路由的增、刪、改、查權限控制。
目錄
- 一、數據庫設計擴展
- 1.1 修改路由表(routes)
- 1.2 修改角色與路由權限表(role_routes)
- 二、后端接口設計
- 2.1 修改獲取路由接口
- 2.2 添加路由權限的接口
- 三、前端實現
- 3.1 動態生成路由
- 3.2 根據權限動態顯示按鈕
- 3.3 在Vuex中存儲用戶權限
- 四、總結
一、數據庫設計擴展
為了實現更細粒度的權限控制,我們需要對數據庫結構做一些修改和擴展,增加對路由權限的支持。每個路由會關聯四個權限:增、刪、改、查。
1.1 修改路由表(routes)
首先,我們要擴展路由表,使其支持每個路由的增、刪、改、查權限。
CREATE TABLE routes (id INT AUTO_INCREMENT PRIMARY KEY,path VARCHAR(255) NOT NULL,component VARCHAR(255) NOT NULL,name VARCHAR(255) NOT NULL,parent_id INT DEFAULT 0,meta JSON DEFAULT NULL, is_enabled BOOLEAN DEFAULT TRUE,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,-- 增、刪、改、查權限permission_create BOOLEAN DEFAULT FALSE,permission_delete BOOLEAN DEFAULT FALSE,permission_update BOOLEAN DEFAULT FALSE,permission_view BOOLEAN DEFAULT TRUE
);
permission_create
:該路由是否具有增權限。permission_delete
:該路由是否具有刪權限。permission_update
:該路由是否具有改權限。permission_view
:該路由是否具有查權限。
1.2 修改角色與路由權限表(role_routes)
在role_routes
表中,新增字段來存儲角色對路由的權限,分別對應增、刪、改、查。
CREATE TABLE role_routes (role_id INT,route_id INT,permission_create BOOLEAN DEFAULT FALSE,permission_delete BOOLEAN DEFAULT FALSE,permission_update BOOLEAN DEFAULT FALSE,permission_view BOOLEAN DEFAULT TRUE,PRIMARY KEY (role_id, route_id),FOREIGN KEY (role_id) REFERENCES roles(id),FOREIGN KEY (route_id) REFERENCES routes(id)
);
- 每條記錄表示角色對某個路由的權限。
二、后端接口設計
在后端,我們需要確保路由的增、刪、改、查權限在獲取路由數據時被正確地返回,并且在路由的操作(如添加、刪除、修改、查看)時進行權限控制。
2.1 修改獲取路由接口
修改/api/get_routes
接口,增加對路由權限的支持,返回每個路由的增、刪、改、查權限信息。
@app.route('/api/get_routes', methods=['GET'])
def get_routes():role_name = request.args.get('role')role = Role.query.filter_by(name=role_name).first()if not role:return jsonify({'message': 'Role not found'}), 404routes = db.session.query(Route).join(RoleRoute).filter(RoleRoute.role_id == role.id).all()routes_data = []for route in routes:role_route = RoleRoute.query.filter_by(role_id=role.id, route_id=route.id).first()routes_data.append({'path': route.path,'component': route.component,'name': route.name,'meta': route.meta,'permissions': {'create': role_route.permission_create,'delete': role_route.permission_delete,'update': role_route.permission_update,'view': role_route.permission_view}})return jsonify(routes_data)
在這個接口中,我們通過RoleRoute
表來獲取每個角色對應的路由權限,并將這些權限一起返回。
2.2 添加路由權限的接口
我們還需要提供一個接口來修改路由權限(即為角色設置增、刪、改、查權限)。
@app.route('/api/set_route_permissions', methods=['POST'])
def set_route_permissions():data = request.jsonrole_id = data['role_id']route_id = data['route_id']permission_create = data['permission_create']permission_delete = data['permission_delete']permission_update = data['permission_update']permission_view = data['permission_view']role_route = RoleRoute.query.filter_by(role_id=role_id, route_id=route_id).first()if not role_route:role_route = RoleRoute(role_id=role_id, route_id=route_id)db.session.add(role_route)role_route.permission_create = permission_createrole_route.permission_delete = permission_deleterole_route.permission_update = permission_updaterole_route.permission_view = permission_viewdb.session.commit()return jsonify({'message': 'Permissions updated successfully'})
該接口接收角色ID、路由ID以及增、刪、改、查權限的設置,并更新數據庫中的權限數據。
三、前端實現
前端需要根據從后端接口獲取的路由信息和權限數據,動態生成路由,并根據權限來控制不同路由下按鈕的顯示與操作權限。
3.1 動態生成路由
前端的路由配置需要動態加載,并在路由生成時判斷當前用戶對該路由的權限。
在router/index.js
中,我們可以根據權限信息來配置動態路由。
import Vue from 'vue';
import Router from 'vue-router';
import store from '../store';Vue.use(Router);const router = new Router({routes: []
});function generateRoutes(routes) {const routeArray = [];routes.forEach(route => {const routeConfig = {path: route.path,name: route.name,component: () => import(`@/views/${route.component}.vue`), // 動態加載組件meta: route.meta,permissions: route.permissions // 保存權限數據};if (route.children && route.children.length > 0) {routeConfig.children = generateRoutes(route.children);}routeArray.push(routeConfig);});return routeArray;
}router.beforeEach(async (to, from, next) => {if (!store.state.routes.length) {const res = await store.dispatch('getRoutes');const routes = generateRoutes(res);routes.forEach(route => {router.addRoute(route);});next({ ...to, replace: true });} else {next();}
});export default router;
3.2 根據權限動態顯示按鈕
前端頁面上的操作按鈕(如增、刪、改、查)需要根據用戶對路由的權限來進行顯示和隱藏。假設每個頁面都有這些按鈕,我們可以使用v-if
指令來根據權限控制顯示與否。
<template><div><button v-if="hasCreatePermission">新增</button><button v-if="hasUpdatePermission">編輯</button><button v-if="hasDeletePermission">刪除</button><button v-if="hasViewPermission">查看</button></div>
</template><script>
export default {computed: {hasCreatePermission() {return this.$store.state.userPermissions.create;},hasUpdatePermission() {return this.$store.state.userPermissions.update;},hasDeletePermission() {return this.$store.state.userPermissions.delete;},hasViewPermission() {return this.$store.state.userPermissions.view;}},created() {this.setPermissions(this.$route.meta.permissions);},methods: {setPermissions(permissions) {this.$store.commit('setUserPermissions', permissions);}}
}
</script>
在這個組件中,我們使用v-if
指令根據權限來顯示對應的按鈕。hasCreatePermission
、hasUpdatePermission
等計算屬性返回當前用戶對該頁面的權限,setPermissions
方法會在頁面加載時設置當前用戶的權限。
3.3 在Vuex中存儲用戶權限
在Vuex中,我們可以存儲用戶的權限數據,并在不同的組件中訪問。
// store.js
export default new Vuex.Store({state: {userPermissions: {create: false,delete: false,update: false,view: true}},mutations: {setUserPermissions(state, permissions) {state.userPermissions = permissions;}},actions: {async getRoutes({ commit }) {const res = await axios.get('/api/get_routes', { params: { role: 'admin' } });commit('setRoutes', res.data);return res.data;}}
});
四、總結
通過以上的設計和實現,我們能夠在前端根據路由和權限動態生成路由,并且為每個路由設置增、刪、改、查等操作的權限。后端負責根據用戶的角色返回對應的權限信息,前端通過vue-router
和vuex
管理動態路由和用戶權限。通過這種方式,系統可以靈活地根據角色和權限來展示不同的功能,并且有效地控制用戶對數據的操作權限。
這種設計方式非常適合復雜權限管理的系統,能夠提供細粒度的權限控制,并且可以隨著業務需求的變化靈活調整。