zoukankan      html  css  js  c++  java
  • 权限组件(14):分配权限功能

    效果图:

    一、URL配置

    rbac/url.py

    ...
    from django.urls import re_path
    ...
    
    from rbac.views import menu
    
    urlpatterns = [
        # 分配权限
        re_path(r'^distribute/permissions/$', menu.distribute_permissions, name='distribute_permissions'),
    ]

    二、视图函数

    rbac/views/menu.py

     

    ...
    from django.shortcuts import HttpResponse, render
    
    from rbac import models
    ...
    
    ...
    def distribute_permissions(request):
        """
        权限分配
        :param request:
        :return:
        """
    
        user_id = request.GET.get('uid')
        user_object = models.UserInfo.objects.filter(id=user_id).first()
    
        if not user_object:
            user_id = None
    
        role_id = request.GET.get('rid')
        role_object = models.Role.objects.filter(id=role_id).first()
    
        if not role_object:
            role_id = None
    
        if request.method == 'POST' and request.POST.get('type') == 'role':
            role_id_list = request.POST.getlist('roles')
            # 用户和角色的关系添加到第三张表(关系表)
            if not user_object:
                return HttpResponse('请选择用户,然后再分配角色')
            user_object.roles.set(role_id_list)
    
        if request.method == 'POST' and request.POST.get('type') == 'permission':
            permission_id_list = request.POST.getlist('permissions')
            if not role_object:
                return HttpResponse('请选择角色然后再分配权限!')
            role_object.permissions.set(permission_id_list)
    
        # 获取当前用户拥有的所有角色
    
        if user_id:
            user_has_roles = user_object.roles.all()
        else:
            user_has_roles = []
    
        user_has_roles_dict = {item.id: None for item in user_has_roles}  # 字典查找速度更快
    
        # 获取当前用户拥有的所有权限
        # 如果选中了角色,优先显示选中角色所拥有的权限
        # 如果没有选角色,才显示用户所拥有的权限
    
        if role_object:  # 选择了角色
            user_has_permissions = role_object.permissions.all()
            user_has_permissions_dict = {item.id: None for item in user_has_permissions}
        elif user_object:  # 未选择角色,但是选择了用户
            user_has_permissions = user_object.roles.filter(permissions__id__isnull=False).values(
                'id', 'permissions').distinct()
            user_has_permissions_dict = {item['permissions']: None for item in user_has_permissions}
        else:
            user_has_permissions_dict = {}
    
        user_list = models.UserInfo.objects.all()
        all_role_list = models.Role.objects.all()
    
        # 用到的知识点:字典里的值和列表里的值用的是同一个内存地址,如果改了字典里的值,列表里相应的值也会被改。
    
        # 所有的一级菜单
        all_menu_list = models.Menu.objects.all().values('id', 'title')
    
        all_menu_dict = {}
    
        for menu_obj in all_menu_list:
            menu_obj['children'] = []  # 用于放二级菜单
            all_menu_dict[menu_obj['id']] = menu_obj
    
        # 所有的二级菜单
        all_second_menu_list = models.Permission.objects.filter(menu__isnull=False).values('id', 'title', 'menu_id')
    
        all_second_menu_dict = {}
    
        for second_menu_obj in all_second_menu_list:
            second_menu_obj['children'] = []  # 用于放三级菜单(具体权限)
            all_second_menu_dict[second_menu_obj['id']] = second_menu_obj
            menu_id = second_menu_obj['menu_id']
            all_menu_dict[menu_id]['children'].append(second_menu_obj)
    
        # 所有的三级菜单(不能做菜单的权限)
        all_permission_list = models.Permission.objects.filter(menu__isnull=True).values('id', 'title', 'pid_id')
    
        for permission_obj in all_permission_list:
            pid = permission_obj['pid_id']
            if not pid:  # 表示数据不合法,也就是菜单和父权限都没有,那就不处理了
                continue
            all_second_menu_dict[pid]['children'].append(permission_obj)
    
        """
          [
              {
                  id:1,
                  title:'业务管理',
                  children:[
                      {
                          'id':1,
                          title:'账单列表',
                          children:[
                              {'id':12, 'title':'添加账单'}
                          ]
                      },
                      {'id':11, 'title':'客户列表'},
                  ]
              },
          ]
              """
    
        context = {
            'user_list': user_list,
            'role_list': all_role_list,
            'all_menu_list': all_menu_list,
            'user_id': user_id,
            'user_has_roles_dict': user_has_roles_dict,
            'user_has_permissions_dict': user_has_permissions_dict,
            'role_id': role_id
        }
        return render(request, 'rbac/distribute_permissions.html', context)
    ...

    三、模板

    rbac/templates/distribute_permissions.html

    {% extends 'layout.html' %}
    {% load rbac %}]
    {% block css %}
    
        <style>
            table {
                font-size: 12px;
            }
    
            .user-area ul {
                padding-left: 20px;
            }
    
            .user-area li {
                cursor: pointer;
                padding: 2px 0;
            }
    
            .user-area li a {
                display: block;
            }
    
            .user-area li.active {
                font-weight: bold;
                color: red;
            }
    
            .user-area li.active a {
                color: red;
            }
    
            .role-area tr td a {
                display: block;
            }
    
            .role-area tr.active {
                background-color: #f1f7fd;
                border-left: 3px solid #fdc00f;
            }
    
            .panel-body {
                font-size: 12px;
            }
    
            .permission-area tr.root {
                background-color: #f1f7fd;
            }
    
            .permission-area tr.root td i {
                margin: 3px;
            }
    
            .permission-area .node {
            }
    
            .permission-area .node input[type='checkbox'] {
                margin: 0 5px;
            }
    
            .permission-area .node .parent {
                padding: 5px 0;
            }
    
            .permission-area .node label {
                font-weight: normal;
                margin-bottom: 0;
                font-size: 12px;
            }
    
            .permission-area .node .children {
                padding: 0 0 0 20px;
            }
    
            .permission-area .node .children .child {
                display: inline-block;
                margin: 2px 5px;
            }
    
            .select-help {
                float: right;
            }
    
            .select-help label {
                font-weight: normal;
                cursor: pointer;
            }
    
            .select-help .check-all {
                float: left;
                display: inline-block;
                margin-right: 8px;
            }
    
        </style>
    {% endblock css %}
    
    {% block content %}
    
    
        <div class="luffy-container">
            <div class="col-md-3 user-area">
                <div class="panel panel-default">
                    <div class="panel-heading">
                        <i class="fa fa-book" aria-hidden="true">用户信息</i>
                    </div>
    
                    <div class="panel-body">
                        <ul>
                            {% for user in user_list %}
                                <li class="{% if user.id|safe == user_id %} active {% endif %}">
                                    <a href="?uid={{ user.id }}">{{ user.name }}</a>
                                </li>
                            {% endfor %}
    
                        </ul>
                    </div>
                </div>
            </div>
    
    
            <div class="col-md-3 role-area">
                <form method="post">
                    {% csrf_token %}
                    <input type="hidden" name="type" value="role">
                    <div class="panel panel-default">
                        <!-- Default panel contents -->
                        <div class="panel-heading">
                            <i class="fa fa-flag" aria-hidden="true">角色信息</i>
                            {% if user_id %}
                                <button class="right btn btn-success" style="padding: 2px 8px;margin:-3px">
                                    <i class="fa fa-plus-circle" aria-hidden="true">保存</i>
                                </button>
                            {% endif %}
                            <div class="panel-body">
                                提示:点击用户才能为其分配权限
                            </div>
                        </div>
                        <table class="table">
                            <thead>
                            <tr>
                                <th>角色</th>
                                <th>选项</th>
                            </tr>
                            </thead>
    
                            <tbody>
                            {% for role in role_list %}
                                <tr class="{% if role.id|safe == role_id %}active{% endif %}">
    
                                    <td>
                                        {% if user_id %}
                                            <a href="?uid={{ user_id }}&rid={{ role.id }}">{{ role.title }}</a>
                                        {% else %}
                                            <a href="?rid={{ role.id }}">{{ role.title }}</a>
                                        {% endif %}
                                    </td>
                                    <td>
                                        <input type="checkbox" name="roles" value="{{ role.id }}"
                                               {% if role.id in user_has_roles_dict %}checked{% endif %}/> <!-- 不用转义 -->
    
                                    </td>
                                </tr>
                            {% endfor %}
                            </tbody>
                        </table>
                    </div>
                </form>
            </div>
    
            <div class="col-md-6 permission-area">
                <form method="post">
                    {% csrf_token %}
                    <input type="hidden" name="type" value="permission">
                    <div class="panel panel-default">
                        <div class="panel-heading">
                            <i class="fa fa-flag" aria-hidden="true">权限分配</i>
                            {% if role_id %}
                                <button class="right btn btn-success btn-xs" style="padding: 2px 8px;margin:-3px">
                                    <i class="fa fa-plus-circle" aria-hidden="true">保存</i>
                                </button>
                            {% endif %}
    
                        </div>
    
    
                        <div class="panel-body" style="color: #d4d4d4;padding:10px  5px;">
                            提示:点击角色后,才能为其分配权限
                        </div>
    
                        <table class="table">
                            <tbody>
                            {% for menu in all_menu_list %}
    
                                <tr class="root">
                                    <td>
                                        <i class="fa fa-caret-down" aria-hidden="true"></i>
                                        {{ menu.title }}
                                        <div class="select-help">
                                            <div class="check-all">
                                                <label for="check_all_{{ menu.id }}">全选</label>
                                                <input type="checkbox" id="check_all_{{ menu.id }}">
                                            </div>
                                        </div>
                                    </td>
                                </tr>
    
                                {% if menu.children %}
                                    <tr class="node">
                                        <td>
                                            {% for second_menu in menu.children %}
                                                <div class="parent">
                                                    <input type="checkbox" id="permission_{{ second_menu.id }}"
                                                           name="permissions" value="{{ second_menu.id }}"
                                                           {% if second_menu.id in user_has_permissions_dict %}checked{% endif %}/>
                                                    <label for="permission_{{ second_menu.id }}">{{ second_menu.title }}
                                                        (菜单)</label>
                                                </div>
    
                                                <div class="children">
                                                    {% for permission in second_menu.children %}
                                                        <div class="child">
                                                            <input type="checkbox" id="permission_{{ permission.id }}"
                                                                   name="permissions" value="{{ permission.id }}"
                                                                   {% if permission.id in user_has_permissions_dict %}checked{% endif %}/>
                                                            <label for="permission_{{ permission.id }}">{{ permission.title }}</label>
                                                        </div>
                                                    {% endfor %}
                                                </div>
                                            {% endfor %}
                                        </td>
                                    </tr>
                                {% endif %}
                            {% endfor %}
                            </tbody>
                        </table>
    
                    </div>
                </form>
            </div>
    
        </div>
    {% endblock content %}
    
    {% block js %}
        <script>
            $(function () {
                $('.check-all input:checkbox').change(function () {
                    $(this).parents('.root').next().find(':checkbox').prop('checked', $(this).prop('checked')) //等于当前(全选)的值
                    // 使用attr设置checked返回的是string类型,用prop才返回bool类型。
                })
            })
        </script>
    {% endblock js %}

    参考:jquery中arrt()和prop()的区别

  • 相关阅读:
    哈希算法原理和一致性哈希算法
    负载均衡之轮循算法
    Mybatis的使用
    Spring与SpringMVC的整合
    编程式事务与声明式事务
    八大排序方法及对Arrays类的排序实现探讨
    单例模式的线程安全性
    HotSpot对象的创建及内存布局
    逃逸分析、栈上分配、标量替换、同步替换
    java编译器和解释器
  • 原文地址:https://www.cnblogs.com/lshedward/p/10540858.html
Copyright © 2011-2022 走看看