ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CRM项目之权限分配6

2021-08-05 15:06:10  阅读:239  来源: 互联网

标签:row menu list 分配 user permissions 权限 id CRM


权限分配思路

在一个页面分为三个面板(左中右三块),分别展示所有用户,所有角色,所有权限。
用户的展示:将所有用户展示,点击用户显示所有角色界面,为该用户分配角色其分配角色。
角色的展示:展示被点击用户所拥有的角色,选中角色对应的checkbox框来为该用户分配权限。
权限的展示:有三层,一级菜单->可做二级菜单的权限->不可做菜单的权限,可做三层循环来展示,为其构造用于循环展示的格式的数据

menu_permission_list = [
        # 一级菜单
        {
            'id': 1,
            'title': '业务管理',
            'children' : [
                # 二级菜单
                {
                    'id': 11,
                    'title': '账单列表',
                    'children': [
                        # 不可做菜单的权限
                        {
                            'id': 3,
                            'title': '添加账单'
                        }
                    ]
                }
            ]
        }
    ]

权限分配页面显示

路由

url(r'^distribute/permissions/', menu.distribute_permissions, name='distribute_permissions')

试图函数,构造权限信息展示的结构

def distribute_permissions(request):
    all_users_list = models.UserInfo.objects.all()
    all_roles_list = models.Role.objects.all()
    # 所有的一级菜单
    all_menu_list = models.Menu.objects.values('id', 'title')
    # 所有二级菜单
    all_second_menu_list = models.Permission.objects.filter(menu__isnull=False).values('id', 'title', 'menu_id')
    # 所有三级菜单
    all_permission_list = models.Permission.objects.filter(menu__isnull=True).values('id', 'title', 'pid_id')

    # 使用字典来同步更新列表中的值,key对应的value和列表中的元素指向的是同一块内存地址。
    all_menu_dict = {}
    all_second_menu_dict = {}
    for item in all_menu_list:
        item['children'] = []
        all_menu_dict[item['id']] = item

    # 二级菜单挂靠到一级菜单下
    for row in all_second_menu_list:
        row['children'] = []
        menu_id = row.get('menu_id')
        all_second_menu_dict[row['id']] = row
        all_menu_dict[menu_id]['children'].append(row)

    # 不能做菜单的权限挂靠到二级菜单
    for row in all_permission_list:
        pid_id = row.get('pid_id')
        if pid_id:
            all_second_menu_dict[pid_id]['children'].append(row)


    return render(
        request,
        'rbac/distribute_permissions.html',
        {
            'user_list': all_users_list,
            'role_list': all_roles_list,
            'menu_list': all_menu_list
        },
    )

模板distribute_permissions.html

{% extends 'layout.html' %}
{% load rbac %}
{% block css %}
	<style>
		tr.active{
			border-left: 3px solid #fdc00f
		}

		.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;
			margi-bottom: 0
			font-size: 12px;
		}
		.permission-area .node .children{
			padding: 0 0 0 25px;
		}
		.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: right;
			display: inline-block;
			margin-right: 8px;
		}

	</style>
{% endblock %}

{% block content %}
    <div class="luffy-container">
		<div class="col-md-3">
			<div class="panel panel-info">
				<!-- Default panel contents -->
				<div class="panel-heading">
					<i class="fa fa-book" aria-hidden="true"></i>用户信息
				</div>

				<!-- Table -->
				<ul>
					{% for row in user_list %}
                    	<li><a href="?uid={{ row.id }}">{{ row.name }}</a></li>
					{% endfor %}
                </ul>
			</div>
		</div>
		<div class="col-md-4">
			<div class="panel panel-info">
				<!-- Default panel contents -->
				<div class="panel-heading">
					<i class="fa fa-book" aria-hidden="true"></i>角色信息
				</div>
				<div class="panel-body">
					提示:选中用户才能为其分配角色
				</div>
				<table class="table">
					<thead>
						<tr>
							<th>角色</th>
							<th>选项</th>
						</tr>
					</thead>
					<tbody>
						{% for row in role_list %}
							<tr>
								<td>{{ row.title }}</td>
								<td><input type="checkbox" name="roles" id="" value="{{ row.id }}"></td>
							</tr>
						{% endfor %}
					</tbody>
				</table>
			</div>
		</div>
		<div class="col-md-5 permission-area">
			<div class="panel panel-info">
				<!-- Default panel contents -->
				<div class="panel-heading">
					<i class="fa fa-book" aria-hidden="true"></i>权限分配
				</div>
				<div class="panel-body">
					提示:选中角色才能为其分配权限
				</div>
				<table class="table">
					<tbody>
						{% for item in menu_list  %}
							<tr class="root">
								<td>
									<i class="fa fa-caret-down" aria-hidden=""></i>
									{{ item.title }}
									<div class="select-help">
										<div class="check-all">
											<label for="check-all_{{ item.id }}">全选</label>
											<input type="checkbox" name="" id="check-all_{{ item.id }}">
										</div>
									</div>
								</td>
							</tr>
							<tr class="node">
								<td>
									{% for node in item.children %}
										<div class="parent">
											<input type="checkbox" name="permissions" id="permission_{{ node.id }}"
												value="{{ node.id }}">
											<label for="permission_{{ node.id }}">{{ node.title }} (菜单)</label>
										</div>
										<div class="children">
											{% for child in node.children %}
												<div class="child">
													<input type="checkbox" name="permissions" id="permission_{{ child.id }}"
													value="{{ child.id }}">
													<label for="permission_{{ child.id }}">{{ child.title }}</label>
												</div>
											{% endfor %}
										</div>
									{% endfor %}
								</td>
							</tr>
						{% endfor %}
					</tbody>
				</table>
			</div>
		</div>

		
    </div>

{% endblock %}

效果
在这里插入图片描述

点击选中的用户展示该用户拥有的角色

根据用户id拿到该用户下的所有角色,将所有角色的id已{'id值':None}的形式存储。

# 筛选出当前用户拥有的角色
    if user_id:
        user_has_roles = user_obj.roles.all()
    else:
        user_has_roles = []
    user_has_roles_dict = {item.id: None for item in user_has_roles}

在前端展示checkbox时进行判断,如果其角色id在user_has_roles_dict中,说明用户已拥有该角色,将其设置为checked,显示为选中。

<tbody>
	{% for row in role_list %}
		<tr>
			<td>{{ row.title }}</td>
			<td><input type="checkbox" name="roles" value="{{ row.id }}" {% if row.id in user_has_roles_dict %}checked{% endif %}></td>
		</tr>
	{% endfor %}
</tbody>

点击选中的用户展示该用户拥有的所有权限

根据用户对象,拿到该用户拥有的所有权限,将权限的id以{‘权限id值’:None}的形式存储,注意跨表,用户表->角色表->拿到角色下的所有权限,角色和权限是多对多关系,获取的到权限可能重复,要做去重。

    # 筛选出当前用户拥有的权限
    if user_id:
        user_has_permissions = user_obj.roles.filter(permissions__id__isnull=False).values('id', 'permissions').distinct()
    else:
        user_has_permissions = []
    user_has_permissions_dict = {item['permissions']: None for item in user_has_permissions}

在前端展示checkbox时进行判断,如果其角色id在user_has_permissions_dict 中,说明用户已拥有该角色,将其设置为checked,显示为选中。

<tr class="node">
	<td>
		{% for node in item.children %}
			<div class="parent">
				<input type="checkbox" name="permissions" id="permission_{{ node.id }}"
					value="{{ node.id }}"{% if node.id in user_has_permissions_dict %}checked{% endif %}>
				<label for="permission_{{ node.id }}">{{ node.title }} (菜单)</label>
			</div>
			<div class="children">
				{% for child in node.children %}
					<div class="child">
						<input type="checkbox" name="permissions" id="permission_{{ child.id }}"
						value="{{ child.id }}" {% if child.id in user_has_permissions_dict %}checked{% endif %}>
						<label for="permission_{{ child.id }}">{{ child.title }}</label>
					</div>
				{% endfor %}
			</div>
		{% endfor %}
	</td>
</tr>

效果:
在这里插入图片描述

点击角色显示角色下的已分配权限信息

点击角色显示该角色选中的样式:

.role-area tr td a{
	display:block;
}
.role-area tr.active{
	background-color:#f1f7fd;
	border-left: 3px solid #fdc00f;
}

有两种情况进行处理:

  1. 在点击了用户后,再点击角色
  2. 直接点击角色
    给用户分配权限,是通过角色间接的分配权限,直接点击角色,显示角色的权限分配
    在这里插入图片描述
    点击用户后,再点击角色,会显示该角色下的权限,给该角色权限进行分配,但是用户分配角色的功能应该不受影响,依旧可以分配角色给用户。点击角色信息的保存,给用户分配角色;点击权限分配的保存,给角色分配权限。
    在这里插入图片描述
    代码实现:
    视图函数
def distribute_permissions(request):
    user_id = request.GET.get('uid')
    role_id = request.GET.get('rid')
    user_obj = models.UserInfo.objects.filter(pk=user_id).first()
    role_obj = models.Role.objects.filter(pk=role_id).first()
    if not user_obj:
        user_id = None
    if not role_obj:
        role_id = None

    # 筛选出当前用户拥有的角色
    if user_id:
        user_has_roles = user_obj.roles.all()
    else:
        user_has_roles = []
    user_has_roles_dict = {item.id: None for item in user_has_roles}
    # 筛选出当前用户拥有的权限
    # 如果选中了角色,优先显示选中角色所有的权限;如果没有选中角色,才显示用户所拥有的权限
    if role_obj:  # 选择了角色
        user_has_permissions = role_obj.permissions.values('id')
        user_has_permissions_dict = {item['id']: None for item in user_has_permissions}
    elif user_obj:  # 选择了用户,没有选择角色
        user_has_permissions = user_obj.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 = {}

    all_users_list = models.UserInfo.objects.all()
    all_roles_list = models.Role.objects.all()
    # 所有的一级菜单
    all_menu_list = models.Menu.objects.values('id', 'title')
    # 所有二级菜单
    all_second_menu_list = models.Permission.objects.filter(menu__isnull=False).values('id', 'title', 'menu_id')
    # 所有三级菜单
    all_permission_list = models.Permission.objects.filter(menu__isnull=True).values('id', 'title', 'pid_id')

    # 使用字典来同步更新列表中的值,key对应的value和列表中的元素指向的是同一块内存地址。
    all_menu_dict = {}
    all_second_menu_dict = {}
    for item in all_menu_list:
        item['children'] = []
        all_menu_dict[item['id']] = item

    # 二级菜单挂靠到一级菜单下
    for row in all_second_menu_list:
        row['children'] = []
        menu_id = row.get('menu_id')
        all_second_menu_dict[row['id']] = row
        all_menu_dict[menu_id]['children'].append(row)

    # 不能做菜单的权限挂靠到二级菜单
    for row in all_permission_list:
        pid_id = row.get('pid_id')
        if pid_id:
            all_second_menu_dict[pid_id]['children'].append(row)


    return render(
        request,
        'rbac/distribute_permissions.html',
        {
            'user_list': all_users_list,
            'role_list': all_roles_list,
            'menu_list': all_menu_list,
            'user_id': user_id,
            'role_id': role_id,
            'user_has_roles_dict': user_has_roles_dict,
            'user_has_permissions_dict': user_has_permissions_dict,
        },
    )

模板

{% extends 'layout.html' %}
{% load rbac %}
{% block css %}
	<style>
		.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;
		}

		.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;
			margi-bottom: 0
			font-size: 12px;
		}
		.permission-area .node .children{
			padding: 0 0 0 25px;
		}
		.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: right;
			display: inline-block;
			margin-right: 8px;
		}

	</style>
{% endblock %}

{% block content %}
    <div class="luffy-container">
		<div class="col-md-3 user-area">
			<div class="panel panel-info">
				<!-- Default panel contents -->
				<div class="panel-heading">
					<i class="fa fa-book" aria-hidden="true"></i>用户信息
				</div>

				<div class="panel-body">
					<ul>
						{% for row in user_list %}
							<li class="{% if user_id == row.id|safe %} active {% endif %}"><a href="?uid={{ row.id }}">{{ row.name }}</a></li>
						{% endfor %}
					</ul>
				</div>
			</div>
		</div>
		<div class="col-md-4 role-area">
			<div class="panel panel-info">
				<!-- Default panel contents -->
				<div class="panel-heading">
					<i class="fa fa-book" aria-hidden="true"></i>角色信息
					{% if user_id %}
						<a href="#" class="right btn btn-primary btx-xs"
						   style="margin: -3px; padding: 2px 8px;">
							<i class="fa fa-save" aria-hidden="true"></i>
							保存
						</a>
					{% endif %}
				</div>
				<div class="panel-body">
					提示:选中用户才能为其分配角色
				</div>
				<table class="table">
					<thead>
						<tr>
							<th>角色</th>
							<th>选项</th>
						</tr>
					</thead>
					<tbody>
						{% for row in role_list %}
							<tr class="{% if row.id|safe == role_id %}active{% endif %}">

								<td>
									{% if user_id %}
										<a href="?uid={{ user_id }}&rid={{ row.id }}">{{ row.title }}</a>
									{% else %}
										<a href="?rid={{ row.id }}">{{ row.title }}</a>
									{% endif %}
								</td>
								<td><input type="checkbox" name="roles" value="{{ row.id }}" {% if row.id in user_has_roles_dict %}checked{% endif %}></td>
							</tr>
						{% endfor %}
					</tbody>
				</table>
			</div>
		</div>
		<div class="col-md-5 permission-area">
			<div class="panel panel-info">
				<!-- Default panel contents -->
				<div class="panel-heading">
					<i class="fa fa-book" aria-hidden="true"></i>权限分配
					{% if role_id %}
						<a href="#" class="right btn btn-primary btx-xs"
						   style="margin: -3px; padding: 2px 8px;">
							<i class="fa fa-save" aria-hidden="true"></i>
							保存
						</a>
					{% endif %}
				</div>
				<div class="panel-body">
					提示:选中角色才能为其分配权限
				</div>
				<table class="table">
					<tbody>
						{% for item in menu_list  %}
							<tr class="root">
								<td>
									<i class="fa fa-caret-down" aria-hidden=""></i>
									{{ item.title }}
									<div class="select-help">
										<div class="check-all">
											<label for="check-all_{{ item.id }}">全选</label>
											<input type="checkbox" name="" id="check-all_{{ item.id }}">
										</div>
									</div>
								</td>
							</tr>
							<tr class="node">
								<td>
									{% for node in item.children %}
										<div class="parent">
											<input type="checkbox" name="permissions" id="permission_{{ node.id }}"
												value="{{ node.id }}"{% if node.id in user_has_permissions_dict %}checked{% endif %}>
											<label for="permission_{{ node.id }}">{{ node.title }} (菜单)</label>
										</div>
										<div class="children">
											{% for child in node.children %}
												<div class="child">
													<input type="checkbox" name="permissions" id="permission_{{ child.id }}"
													value="{{ child.id }}" {% if child.id in user_has_permissions_dict %}checked{% endif %}>
													<label for="permission_{{ child.id }}">{{ child.title }}</label>
												</div>
											{% endfor %}
										</div>
									{% endfor %}
								</td>
							</tr>
						{% endfor %}
					</tbody>
				</table>
			</div>
		</div>

		
    </div>

{% endblock %}

权限分配页面保存按钮

有两个保存按钮,一个是角色分配的保存按钮,一个是权限分配的保存按钮。也就是说点击会有两个form表单提交到同一url到后台,后台需要区分不同的表单进行处理,区分的方式是在各自的form下写一个intput标签<input type="text" name="type" value="permission" hidden> <input type="text" name="type" value="permission" hidden>后台获取提交的input的标签内容来区分不同的表单

if request.method == "POST" and request.POST.get('type') == "role":
    print('角色')

if request.method == "POST" and request.POST.get('type') == "permission":
    print('权限')

后端进行保存:

    if request.method == "POST" and request.POST.get('type') == "role":
        role_id_list = request.POST.getlist('roles')
        if not user_obj:
            return HttpResponse('请选择用户,再分配角色')
        user_obj.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_obj:
            return HttpResponse('请选择角色,再分配权限')
        role_obj.permissions.set(permission_id_list)

权限分配之全选

使用js来实现,再点击权限时,给每个input checkbox标签加上checked就可以

{% block js %}
<script type="text/javascript">
	$(function(){
		$('.check-all input:checkbox').change(function(){
			$(this).parents('.root').next().find(':checkbox').prop('checked', $(this).prop('checked'))
		})
	})
</script>
{% endblock %}

标签:row,menu,list,分配,user,permissions,权限,id,CRM
来源: https://blog.csdn.net/no_name_sky/article/details/119354276

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有