• 基于Python-Flask的权限管理4:加载菜单


    一、前言

    本文实现了根据不同用户加载不同的菜单权限。

    二、修改前端

    前端登录成功之后会加载菜单,发送了一个find_all_menu请求,该请求会根据用户ID加载菜单,但是在项目组它并没有传id直接后端写死了,所以我们要改下前端。

    1.修改srcapimodulesmenu.js的MENU_USER方法,使这个方法传用户id

    2.修改srcstoremodulesd2adminmodulespermission.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.点击登录之后,成功显示权限

  • 相关阅读:
    差分约束
    DevOps系列【centos 7离线安装中文版GitLab】
    Linux系列【硬盘的插入、分区、格式化、挂载】
    并发编程系列【ThreadLocal】
    Linux系列【从一台linux通过ssh登录另一台linux服务器】
    idea系列【配置git忽略文件和目录规则】
    网络编程系列【文件上传(C/S)】
    常见的问题系列【tar: Error is not recoverable: exiting now】
    网络编程系列【TCP通信原理】
    DevOps系列【Jenkinsfile+Dockerfile+nginx+vue】
  • 原文地址:https://www.cnblogs.com/huguodong/p/12592187.html
Copyright © 2020-2023  润新知