一、前言
本文實現了根據不同用戶加載不同的菜單權限。
二、修改前端
前端登錄成功之后會加載菜單,發送了一個find_all_menu請求,該請求會根據用戶ID加載菜單,但是在項目組它並沒有傳id直接后端寫死了,所以我們要改下前端。
1.修改src\api\modules\menu.js的MENU_USER方法,使這個方法傳用戶id
2.修改src\store\modules\d2admin\modules\permission.js 使MENU_USERc傳入UUID
三、根據用戶顯示菜單
1.菜單權限表ORM
from models.BaseModel import BaseModel from db import db class Menu(BaseModel): """ 菜單權限表 """ __tablename__ = "t_menu" id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment="菜單ID") menu_name = db.Column(db.String(50), comment="菜單名稱") parent_id = db.Column(db.Integer, comment="父菜單ID") order_num = db.Column(db.Integer, comment="顯示順序") url = db.Column(db.String(200), comment="請求地址") menu_type = db.Column(db.Integer, default=1, comment="菜單類型(1,目錄 2,菜單 3,按鈕") visible = db.Column(db.Integer, default=1, comment="菜單狀態(1顯示 2隱藏)") perms = db.Column(db.String(100), comment="權限標識") icon = db.Column(db.String(100), comment="菜單圖標") is_frame = db.Column(db.Integer, default=2, comment="是否外鏈") route_name = db.Column(db.String(100), default="", comment="路由名稱") route_path = db.Column(db.String(100), default="", comment="路由地址") route_cache = db.Column(db.Integer, default=0, comment="路由緩存") route_component = db.Column(db.String(100), default="", comment="路由組件")
2.角色菜單關系表ORM
from db import db from models.BaseModel import BaseModel class Role_Menu(BaseModel): """ 角色菜單關聯表 """ __tablename__ = "t_role_menu" id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment="ID") role_id = db.Column(db.Integer, comment="角色ID") menu_id = db.Column(db.Integer, comment="菜單ID") create_by = None created_at = None update_by = None updated_at = None remark = None
3.用戶角色關系表ORM
from db import db from models.BaseModel import BaseModel class User_Role(BaseModel): """ 用戶角色關聯表 """ __tablename__ = "t_user_role" id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment="ID") user_id = db.Column(db.Integer, comment="用戶ID") role_id = db.Column(db.Integer, comment="角色ID") create_by = None created_at = None update_by = None updated_at = None remark = None
4.permission下新建menu.py,並在app.py注冊藍圖
from permission import * menu = Blueprint('menu', __name__)
app.register_blueprint(menu.menu, url_prefix='/api/menu')
5.find_all_menu接口實現
@menu.route('/find_all_menu', methods=["POST"]) # @login_required def find_all_menu(): ''' 根據用戶id獲取菜單 :return: ''' res_dir = request.get_json() user_id = res_dir.get("uuid") data = constructMenuTrees(user_id=user_id) # 獲取菜單樹 return jsonify(code=Code.SUCCESS.value, msg="ok", data=data)
通過遞歸實現根據父ID查找子菜單,如果傳入用戶id則只查詢該用戶的權限否則查詢所有權限,一級菜單父id默認是0
def constructMenuTrees(parentId=0, user_id=None): ''' 通過遞歸實現根據父ID查找子菜單,如果傳入用戶id則只查詢該用戶的權限否則查詢所有權限,一級菜單父id默認是0 1.根據父ID獲取該菜單下的子菜單或權限 2.遍歷子菜單或權限,繼續向下獲取,直到最小級菜單或權限 3.如果沒有遍歷到,返回空的數組,有返回權限列表 :param user_id: :param parentId: :return:dict ''' if user_id: menu_data = Menu.query.join(Role_Menu, Menu.id == Role_Menu.menu_id).join(User_Role, User_Role.role_id == Role_Menu.role_id).filter( User_Role.user_id == user_id).filter(Menu.parent_id == parentId).order_by('order_num').all() else: menu_data = Menu.query.filter(Menu.parent_id == parentId).order_by('order_num').all() menu_dict = menu_to_dict(menu_data) if len(menu_dict) > 0: data = [] for menu in menu_dict: menu['children_list'] = constructMenuTrees(menu['id'], user_id) data.append(menu) return data return []
查詢出來的數據是無序的,前端顯示不夠直白,這邊格式化一下
def menu_to_dict(result): ''' 格式化菜單字段顯示順序 :param result: :return: ''' data = [] for menu in result: child = { "id": menu.id, "menu_name": menu.menu_name, "parent_id": menu.parent_id, "order_num": menu.order_num, "url": menu.url, "menu_type": menu.menu_type, "visible": menu.visible, "perms": menu.perms, "icon": menu.icon, "is_frame": menu.is_frame, "create_by": menu.create_by, "created_at": menu.created_at, "update_by": menu.update_by, "updated_at": menu.updated_at, "remark": menu.remark, "route_name": menu.route_name, "route_path": menu.route_path, "route_cache": menu.route_cache, "route_component": menu.route_component, } data.append(child) return data
6.點擊登錄之后,成功顯示權限