From 6d3f57af21f23f990e4e3081ce574a6e3129986b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BC=BA?= <1206709430@qq.com> Date: Mon, 22 Mar 2021 21:23:48 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=9D=83=E9=99=90=E7=94=B1?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E4=BA=BA=E5=8F=98=E4=B8=BA=20=E6=89=80?= =?UTF-8?q?=E5=B1=9E=E9=83=A8=E9=97=A8=20=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dvadmin-backend/apps/vadmin/op_drf/filters.py | 59 +++++++++++-------- .../apps/vadmin/op_drf/middleware.py | 10 ++++ dvadmin-backend/apps/vadmin/op_drf/models.py | 1 + .../apps/vadmin/op_drf/serializers.py | 4 ++ dvadmin-backend/apps/vadmin/system/views.py | 1 + dvadmin-ui/src/utils/ruoyi.js | 3 +- .../views/vadmin/permission/role/index.vue | 6 -- 7 files changed, 51 insertions(+), 33 deletions(-) diff --git a/dvadmin-backend/apps/vadmin/op_drf/filters.py b/dvadmin-backend/apps/vadmin/op_drf/filters.py index b6ce37f..8b06305 100644 --- a/dvadmin-backend/apps/vadmin/op_drf/filters.py +++ b/dvadmin-backend/apps/vadmin/op_drf/filters.py @@ -6,7 +6,6 @@ import logging import operator from functools import reduce -from django.db.models import Q from django.utils import six from mongoengine.queryset import visitor from rest_framework.filters import BaseFilterBackend, SearchFilter, OrderingFilter @@ -102,45 +101,55 @@ class MongoAdvancedSearchFilter(BaseFilterBackend): class DataLevelPermissionsFilter(BaseFilterBackend): """ 数据 级权限过滤器 - 0. 判断过滤的数据是否有创建人 "creator" 字段 - 1. 判断用户是否为超级管理员角色 - 2. 根据角色的最大权限进行数据过滤(会有多个角色,进行去重取最大权限) - 3. 只为仅本人数据权限时只返回过滤本人数据 - 4. 自定数据权限 获取部门,根据部门过滤 + 0. 获取用户的部门id,没有部门则返回空 + 1. 判断过滤的数据是否有创建人所在部门 "creator" 字段,没有则返回全部 + 2. 如果用户没有关联角色则返回本部门数据 + 3. 根据角色的最大权限进行数据过滤(会有多个角色,进行去重取最大权限) + 3.1 判断用户是否为超级管理员角色/如果有1(所有数据) 则返回所有数据 + + 4. 只为仅本人数据权限时只返回过滤本人数据,并且部门为自己本部门(考虑到用户会变部门,只能看当前用户所在的部门数据) + 5. 自定数据权限 获取部门,根据部门过滤 """ - project_resource_name: str = 'project__tenant__managers' def filter_queryset(self, request, queryset, view): - # 0. 判断过滤的数据是否有创建人 "creator" 字段 - if not hasattr(queryset.model, 'creator'): + # 0. 获取用户的部门id,没有部门则返回空 + user_dept_id = getattr(request.user, 'dept_id') + if not user_dept_id: + return queryset.none() + + # 1. 判断过滤的数据是否有创建人所在部门 "dept_belong_id" 字段 + if not hasattr(queryset.model, 'dept_belong_id'): return queryset - # 1. 判断用户是否为超级管理员角色 + + # 2. 如果用户没有关联角色则返回本部门数据 if not hasattr(request.user, 'role'): - return queryset.filter(creator=request.user) - role_list = request.user.role.all().values('id', 'admin', 'dataScope') - if True in list(set([ele.get('admin') for ele in role_list])): - return queryset + return queryset.filter(dept_belong_id=user_dept_id) - # 2. 根据角色的最大权限进行数据过滤(会有多个角色,进行去重取最大权限) - dataScope_list = list(set([ele.get('dataScope') for ele in role_list])) - if '1' in dataScope_list: # 返回所有数据 - return queryset + # 3. 根据所有角色 获取所有权限范围 + role_list = request.user.role.all().values('admin', 'dataScope') + dataScope_list = [] + for ele in role_list: + # 3.1 判断用户是否为超级管理员角色/如果有1(所有数据) 则返回所有数据 + if '1' == ele.get('dataScope') or ele.get('admin') == True: + return queryset + dataScope_list.append(ele.get('dataScope')) + dataScope_list = list(set(dataScope_list)) - # 3. 只为仅本人数据权限时只返回过滤本人数据 + # 4. 只为仅本人数据权限时只返回过滤本人数据,并且部门为自己本部门(考虑到用户会变部门,只能看当前用户所在的部门数据) if dataScope_list == ['5']: - return queryset.filter(Q(creator=request.user)) + return queryset.filter(creator=request.user, dept_belong_id=request.user.dept_id) - # 4. 自定数据权限 获取部门,根据部门过滤 + # 5. 自定数据权限 获取部门,根据部门过滤 dept_list = [] for ele in dataScope_list: if ele == '2': dept_list.extend(request.user.role.all().values_list('dept__id', flat=True)) elif ele == '3': - dept_list.append(request.user.dept.id) + dept_list.append(user_dept_id) elif ele == '4': - dept_list.extend(self.get_dept(request.user.dept.id, Dept.objects.all().values('id', 'parentId'))) - dept_list.append(request.user.dept.id) - return queryset.filter(Q(creator=request.user) | Q(creator__dept__in=list(set(dept_list)))) + dept_list.extend(self.get_dept(user_dept_id, Dept.objects.all().values('id', 'parentId'))) + dept_list.append(user_dept_id) + return queryset.filter(dept_belong_id__in=list(set(dept_list))) def get_dept(self, id, dept_all_list, dept_list=[]): """ diff --git a/dvadmin-backend/apps/vadmin/op_drf/middleware.py b/dvadmin-backend/apps/vadmin/op_drf/middleware.py index 9f75f4e..ad3f98d 100644 --- a/dvadmin-backend/apps/vadmin/op_drf/middleware.py +++ b/dvadmin-backend/apps/vadmin/op_drf/middleware.py @@ -3,6 +3,7 @@ django中间件 """ from django.conf import settings +from django.contrib.auth.models import AnonymousUser from django.utils.deprecation import MiddlewareMixin from apps.vadmin.system.models import OperationLog @@ -38,6 +39,7 @@ class ApiLoggingMiddleware(MiddlewareMixin): info = { 'request_ip': getattr(request, 'request_ip', 'unknown'), 'creator': request.user, + 'dept_belong_id': getattr(request.user, 'dept_id', None), 'request_method': request.method, 'request_path': request.request_path, 'request_body': body, @@ -50,6 +52,8 @@ class ApiLoggingMiddleware(MiddlewareMixin): 'json_result': {"code": response.data.get('code'), "msg": response.data.get('msg')}, 'request_modular': request.session.get('model_name'), } + if isinstance(request.user, AnonymousUser): + info['creator'] = None log = OperationLog(**info) log.save() @@ -67,3 +71,9 @@ class ApiLoggingMiddleware(MiddlewareMixin): if self.methods == 'ALL' or request.method in self.methods: self.__handle_response(request, response) return response + + +class PermissionModeMiddleware(MiddlewareMixin): + """ + 权限模式拦截判断 + """ diff --git a/dvadmin-backend/apps/vadmin/op_drf/models.py b/dvadmin-backend/apps/vadmin/op_drf/models.py index a8473e5..1eead22 100644 --- a/dvadmin-backend/apps/vadmin/op_drf/models.py +++ b/dvadmin-backend/apps/vadmin/op_drf/models.py @@ -27,6 +27,7 @@ class CoreModel(models.Model): creator = models.ForeignKey(to='permission.UserProfile', related_query_name='creator_query', null=True, verbose_name='创建者', on_delete=SET_NULL, db_constraint=False) # 创建者 modifier = ModifierCharField() # 修改者 + dept_belong_id = models.CharField(max_length=64, verbose_name="数据归属部门", null=True, blank=True) update_datetime = UpdateDateTimeField() # 修改时间 create_datetime = CreateDateTimeField() # 创建时间 diff --git a/dvadmin-backend/apps/vadmin/op_drf/serializers.py b/dvadmin-backend/apps/vadmin/op_drf/serializers.py index 0c9a9c0..5e47537 100644 --- a/dvadmin-backend/apps/vadmin/op_drf/serializers.py +++ b/dvadmin-backend/apps/vadmin/op_drf/serializers.py @@ -15,6 +15,8 @@ class CustomModelSerializer(ModelSerializer): modifier_field_name = 'modifier' # 创建人的审计字段名称, 默认creator, 继承使用时可自定义覆盖 creator_field_name = 'creator' + # 数据所属部门字段 + dept_belong_id_field_name = 'dept_belong_id' # 添加默认时间返回格式 create_datetime = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True) update_datetime = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True) @@ -33,6 +35,8 @@ class CustomModelSerializer(ModelSerializer): validated_data[self.modifier_field_name] = username if self.creator_field_name in self.fields.fields: validated_data[self.creator_field_name] = self.request.user + if self.dept_belong_id_field_name in self.fields.fields: + validated_data[self.dept_belong_id_field_name] = getattr(self.request.user,'dept_id',None) return super().create(validated_data) def update(self, instance, validated_data): diff --git a/dvadmin-backend/apps/vadmin/system/views.py b/dvadmin-backend/apps/vadmin/system/views.py index dbec318..61292ef 100644 --- a/dvadmin-backend/apps/vadmin/system/views.py +++ b/dvadmin-backend/apps/vadmin/system/views.py @@ -28,6 +28,7 @@ class DictDataModelViewSet(CustomModelViewSet): update_serializer_class = DictDataCreateUpdateSerializer # list_serializer_class = ListRoleSerializer # retrieve_serializer_class = DetailRoleSerializer + extra_filter_backends = [DataLevelPermissionsFilter] filter_class = DictDataFilter # update_extra_permission_classes = (IsManagerPermission,) # destroy_extra_permission_classes = (IsManagerPermission,) diff --git a/dvadmin-ui/src/utils/ruoyi.js b/dvadmin-ui/src/utils/ruoyi.js index 58d8bb8..b1f39be 100755 --- a/dvadmin-ui/src/utils/ruoyi.js +++ b/dvadmin-ui/src/utils/ruoyi.js @@ -56,7 +56,7 @@ export function resetForm(refName) { // 添加日期范围 export function addDateRange(params, dateRange, propName) { let search = JSON.parse(JSON.stringify(params)); - if (dateRange.length !== 0) { + if (null != dateRange && '' !== dateRange && dateRange.length !== 0) { search.as = JSON.stringify({create_datetime__range : dateRange}); } return search; @@ -67,7 +67,6 @@ export function selectDictLabel(datas, value) { var actions = []; Object.keys(datas).some((key) => { if (String(datas[key].dictValue) === ('' + String(value))) { - actions.push(datas[key].dictLabel); actions.push(datas[key].dictLabel); return true; } diff --git a/dvadmin-ui/src/views/vadmin/permission/role/index.vue b/dvadmin-ui/src/views/vadmin/permission/role/index.vue index 9e74b36..cb486b5 100755 --- a/dvadmin-ui/src/views/vadmin/permission/role/index.vue +++ b/dvadmin-ui/src/views/vadmin/permission/role/index.vue @@ -369,12 +369,6 @@ export default { this.menuOptions = this.handleTree(response.data,'id'); }); }, - /** 查询部门树结构 */ - getDeptTreeselect() { - deptTreeselect().then(response => { - this.deptOptions = response.data; - }); - }, // 所有菜单节点数据 getMenuAllCheckedKeys() { // 目前被选中的菜单节点