From 10b159aa1514c7b13fe2dbb1a0b41ebc0dde91c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8C=BF=E5=B0=8F=E5=A4=A9?= <1638245306@qq.com> Date: Sun, 29 Oct 2023 00:33:07 +0800 Subject: [PATCH] =?UTF-8?q?1.=E5=AE=8C=E6=88=90=E6=96=B0=E7=89=88=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E6=8E=88=E6=9D=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/dvadmin/system/models.py | 24 +- backend/dvadmin/system/urls.py | 6 +- backend/dvadmin/system/views/dept.py | 4 +- backend/dvadmin/system/views/menu.py | 23 +- backend/dvadmin/system/views/menu_button.py | 72 ------ backend/dvadmin/system/views/role.py | 14 +- ...n_permission.py => role_api_permission.py} | 155 ++----------- backend/dvadmin/system/views/role_menu.py | 2 +- backend/dvadmin/utils/filters.py | 11 +- backend/dvadmin/utils/permission.py | 14 +- web/src/plugin/permission/store.permission.ts | 2 +- .../role/components/ApiPermission/api.ts | 57 +++++ .../role/components/ApiPermission/crud.tsx | 207 ++++++++++++++++++ .../role/components/ApiPermission/index.vue | 59 +++++ .../views/system/role/components/index.vue | 24 +- web/src/views/system/role/crud.tsx | 40 +--- 16 files changed, 402 insertions(+), 312 deletions(-) delete mode 100644 backend/dvadmin/system/views/menu_button.py rename backend/dvadmin/system/views/{role_menu_button_permission.py => role_api_permission.py} (53%) create mode 100644 web/src/views/system/role/components/ApiPermission/api.ts create mode 100644 web/src/views/system/role/components/ApiPermission/crud.tsx create mode 100644 web/src/views/system/role/components/ApiPermission/index.vue diff --git a/backend/dvadmin/system/models.py b/backend/dvadmin/system/models.py index 26abd1e..71d23fc 100644 --- a/backend/dvadmin/system/models.py +++ b/backend/dvadmin/system/models.py @@ -252,7 +252,7 @@ class RoleMenuPermission(CoreModel): # ordering = ("-create_datetime",) -class RoleMenuButtonPermission(CoreModel): +class RoleApiPermission(CoreModel): role = models.ForeignKey( to="Role", db_constraint=False, @@ -261,16 +261,16 @@ class RoleMenuButtonPermission(CoreModel): verbose_name="关联角色", help_text="关联角色", ) - menu_button = models.ForeignKey( - to="MenuButton", - db_constraint=False, - related_name="menu_button_permission", - on_delete=models.CASCADE, - verbose_name="关联菜单按钮", - help_text="关联菜单按钮", - null=True, - blank=True + name = models.CharField(max_length=64, verbose_name="名称", help_text="名称") + api = models.CharField(max_length=200, verbose_name="接口地址", help_text="接口地址") + METHOD_CHOICES = ( + (0, "GET"), + (1, "POST"), + (2, "PUT"), + (3, "DELETE"), ) + method = models.IntegerField(default=0, verbose_name="接口请求方法", null=True, blank=True, + help_text="接口请求方法") DATASCOPE_CHOICES = ( (0, "仅本人数据权限"), (1, "本部门及以下数据权限"), @@ -284,8 +284,8 @@ class RoleMenuButtonPermission(CoreModel): help_text="数据权限-关联部门") class Meta: - db_table = table_prefix + "role_menu_button_permission" - verbose_name = "角色按钮权限表" + db_table = table_prefix + "role_api_permission" + verbose_name = "角色接口权限表" verbose_name_plural = verbose_name ordering = ("-create_datetime",) diff --git a/backend/dvadmin/system/urls.py b/backend/dvadmin/system/urls.py index 4e11c04..66a2f95 100644 --- a/backend/dvadmin/system/urls.py +++ b/backend/dvadmin/system/urls.py @@ -8,19 +8,17 @@ from dvadmin.system.views.dictionary import DictionaryViewSet from dvadmin.system.views.file_list import FileViewSet from dvadmin.system.views.login_log import LoginLogViewSet from dvadmin.system.views.menu import MenuViewSet -from dvadmin.system.views.menu_button import MenuButtonViewSet from dvadmin.system.views.message_center import MessageCenterViewSet from dvadmin.system.views.operation_log import OperationLogViewSet from dvadmin.system.views.role import RoleViewSet from dvadmin.system.views.role_menu import RoleMenuPermissionViewSet -from dvadmin.system.views.role_menu_button_permission import RoleMenuButtonPermissionViewSet +from dvadmin.system.views.role_api_permission import RoleApiPermissionViewSet from dvadmin.system.views.system_config import SystemConfigViewSet from dvadmin.system.views.user import UserViewSet from dvadmin.system.views.column import ColumnViewSet system_url = routers.SimpleRouter() system_url.register(r'menu', MenuViewSet) -system_url.register(r'menu_button', MenuButtonViewSet) system_url.register(r'role', RoleViewSet) system_url.register(r'dept', DeptViewSet) system_url.register(r'user', UserViewSet) @@ -31,7 +29,7 @@ system_url.register(r'file', FileViewSet) system_url.register(r'api_white_list', ApiWhiteListViewSet) system_url.register(r'system_config', SystemConfigViewSet) system_url.register(r'message_center', MessageCenterViewSet) -system_url.register(r'role_menu_button_permission', RoleMenuButtonPermissionViewSet) +system_url.register(r'role_api_permission', RoleApiPermissionViewSet) system_url.register(r'role_menu_permission', RoleMenuPermissionViewSet) system_url.register(r'column', ColumnViewSet) diff --git a/backend/dvadmin/system/views/dept.py b/backend/dvadmin/system/views/dept.py index 8d06c30..47e3968 100644 --- a/backend/dvadmin/system/views/dept.py +++ b/backend/dvadmin/system/views/dept.py @@ -9,7 +9,7 @@ from rest_framework import serializers from rest_framework.decorators import action from rest_framework.permissions import IsAuthenticated -from dvadmin.system.models import Dept, RoleMenuButtonPermission, Users +from dvadmin.system.models import Dept, RoleApiPermission, Users from dvadmin.utils.json_response import DetailResponse, SuccessResponse, ErrorResponse from dvadmin.utils.serializers import CustomModelSerializer from dvadmin.utils.viewset import CustomModelViewSet @@ -135,7 +135,7 @@ class DeptViewSet(CustomModelViewSet): queryset = Dept.objects.values('id', 'name', 'parent') else: role_ids = request.user.role.values_list('id', flat=True) - data_range = RoleMenuButtonPermission.objects.filter(role__in=role_ids).values_list('data_range', flat=True) + data_range = RoleApiPermission.objects.filter(role__in=role_ids).values_list('data_range', flat=True) user_dept_id = request.user.dept.id dept_list = [user_dept_id] data_range_list = list(set(data_range)) diff --git a/backend/dvadmin/system/views/menu.py b/backend/dvadmin/system/views/menu.py index 88dd52f..24bb906 100644 --- a/backend/dvadmin/system/views/menu.py +++ b/backend/dvadmin/system/views/menu.py @@ -8,9 +8,9 @@ """ from rest_framework import serializers from rest_framework.decorators import action +from rest_framework.permissions import IsAuthenticated from dvadmin.system.models import Menu, RoleMenuPermission -from dvadmin.system.views.menu_button import MenuButtonSerializer from dvadmin.utils.json_response import SuccessResponse, ErrorResponse, DetailResponse from dvadmin.utils.serializers import CustomModelSerializer from dvadmin.utils.viewset import CustomModelViewSet @@ -104,6 +104,9 @@ class MenuViewSet(CustomModelViewSet): @action(methods=['get'], detail=True) def getChildren(self,request,pk): + """ + 获取子菜单,用于菜单页面的懒加载 + """ queryset = Menu.objects.filter(parent=pk) serializer = MenuSerializer(queryset, many=True, request=request) data = serializer.data @@ -113,17 +116,31 @@ class MenuViewSet(CustomModelViewSet): def web_router(self, request): """用于前端获取当前角色的路由""" user = request.user - is_admin = user.role.values_list('admin', flat=True) if user.is_superuser: queryset = self.queryset.filter(status=1) else: role_list = user.role.values_list('id', flat=True) menu_list = RoleMenuPermission.objects.filter(role__in=role_list).values_list('menu_id', flat=True) - queryset = Menu.objects.filter(id__in=menu_list) + queryset = Menu.objects.filter(id__in=menu_list,menu_type__in=[0,1]) serializer = WebRouterSerializer(queryset, many=True, request=request) data = serializer.data return SuccessResponse(data=data, total=len(data), msg="获取成功") + @action(methods=['get'], detail=False, permission_classes=[IsAuthenticated]) + def menu_button_all_permission(self, request): + """ + 获取所有的按钮权限 + :param request: + :return: + """ + is_superuser = request.user.is_superuser + if is_superuser: + queryset = Menu.objects.filter(menu_type=2).values_list('component', flat=True) + else: + role_id = request.user.role.values_list('id', flat=True) + queryset = Menu.objects.filter(role__in=role_id,menu_type=2).values_list('component',flat=True).distinct() + return DetailResponse(data=queryset) + @action(methods=['GET'], detail=False, permission_classes=[]) def get_all_menu(self, request): """用于菜单管理获取所有的菜单""" diff --git a/backend/dvadmin/system/views/menu_button.py b/backend/dvadmin/system/views/menu_button.py deleted file mode 100644 index 94a65ef..0000000 --- a/backend/dvadmin/system/views/menu_button.py +++ /dev/null @@ -1,72 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -@author: 猿小天 -@contact: QQ:1638245306 -@Created on: 2021/6/3 003 0:30 -@Remark: 菜单按钮管理 -""" -from django.db.models import F -from rest_framework.decorators import action -from rest_framework.permissions import IsAuthenticated - -from dvadmin.system.models import MenuButton, RoleMenuButtonPermission -from dvadmin.utils.json_response import DetailResponse -from dvadmin.utils.serializers import CustomModelSerializer -from dvadmin.utils.viewset import CustomModelViewSet - - -class MenuButtonSerializer(CustomModelSerializer): - """ - 菜单按钮-序列化器 - """ - - class Meta: - model = MenuButton - fields = ['id', 'name', 'value', 'api', 'method','menu'] - read_only_fields = ["id"] - - - - -class MenuButtonCreateUpdateSerializer(CustomModelSerializer): - """ - 初始化菜单按钮-序列化器 - """ - - class Meta: - model = MenuButton - fields = "__all__" - read_only_fields = ["id"] - - -class MenuButtonViewSet(CustomModelViewSet): - """ - 菜单按钮接口 - list:查询 - create:新增 - update:修改 - retrieve:单例 - destroy:删除 - """ - queryset = MenuButton.objects.all() - serializer_class = MenuButtonSerializer - create_serializer_class = MenuButtonCreateUpdateSerializer - update_serializer_class = MenuButtonCreateUpdateSerializer - extra_filter_class = [] - - @action(methods=['get'],detail=False,permission_classes=[IsAuthenticated]) - def menu_button_all_permission(self,request): - """ - 获取所有的按钮权限 - :param request: - :return: - """ - is_superuser = request.user.is_superuser - is_admin = request.user.role.values_list('admin', flat=True) - if is_superuser or True in is_admin: - queryset = MenuButton.objects.values_list('value',flat=True) - else: - role_id = request.user.role.values_list('id', flat=True) - queryset = RoleMenuButtonPermission.objects.filter(role__in=role_id).values_list('menu_button__value',flat=True).distinct() - return DetailResponse(data=queryset) \ No newline at end of file diff --git a/backend/dvadmin/system/views/role.py b/backend/dvadmin/system/views/role.py index ccbe6d6..343634f 100644 --- a/backend/dvadmin/system/views/role.py +++ b/backend/dvadmin/system/views/role.py @@ -13,7 +13,6 @@ from rest_framework.permissions import IsAuthenticated from dvadmin.system.models import Role, Menu, MenuButton, Dept from dvadmin.system.views.dept import DeptSerializer from dvadmin.system.views.menu import MenuSerializer -from dvadmin.system.views.menu_button import MenuButtonSerializer from dvadmin.utils.crud_mixin import FastCrudMixin from dvadmin.utils.field_permission import FieldPermissionMixin from dvadmin.utils.json_response import SuccessResponse, DetailResponse @@ -39,7 +38,6 @@ class RoleCreateUpdateSerializer(CustomModelSerializer): """ menu = MenuSerializer(many=True, read_only=True) dept = DeptSerializer(many=True, read_only=True) - permission = MenuButtonSerializer(many=True, read_only=True) key = serializers.CharField(max_length=50, validators=[CustomUniqueValidator(queryset=Role.objects.all(), message="权限字符必须唯一")]) name = serializers.CharField(max_length=50, validators=[CustomUniqueValidator(queryset=Role.objects.all())]) @@ -63,21 +61,11 @@ class MenuPermissionSerializer(CustomModelSerializer): """ 菜单的按钮权限 """ - menuPermission = serializers.SerializerMethodField() - def get_menuPermission(self, instance): - is_superuser = self.request.user.is_superuser - if is_superuser: - queryset = MenuButton.objects.filter(menu__id=instance.id) - else: - menu_permission_id_list = self.request.user.role.values_list('permission', flat=True) - queryset = MenuButton.objects.filter(id__in=menu_permission_id_list, menu__id=instance.id) - serializer = MenuButtonSerializer(queryset, many=True, read_only=True) - return serializer.data class Meta: model = Menu - fields = ['id', 'parent', 'name', 'menuPermission'] + fields = ['id', 'parent', 'name'] class MenuButtonPermissionSerializer(CustomModelSerializer): diff --git a/backend/dvadmin/system/views/role_menu_button_permission.py b/backend/dvadmin/system/views/role_api_permission.py similarity index 53% rename from backend/dvadmin/system/views/role_menu_button_permission.py rename to backend/dvadmin/system/views/role_api_permission.py index f43b4ee..49653b7 100644 --- a/backend/dvadmin/system/views/role_menu_button_permission.py +++ b/backend/dvadmin/system/views/role_api_permission.py @@ -11,25 +11,25 @@ from rest_framework import serializers from rest_framework.decorators import action from rest_framework.permissions import IsAuthenticated -from dvadmin.system.models import RoleMenuButtonPermission, Menu, MenuButton, Dept, RoleMenuPermission, Columns +from dvadmin.system.models import RoleApiPermission, Menu, MenuButton, Dept, RoleMenuPermission, Columns from dvadmin.system.views.menu import MenuSerializer from dvadmin.utils.json_response import DetailResponse, ErrorResponse from dvadmin.utils.serializers import CustomModelSerializer from dvadmin.utils.viewset import CustomModelViewSet -class RoleMenuButtonPermissionSerializer(CustomModelSerializer): +class RoleApiPermissionSerializer(CustomModelSerializer): """ 菜单按钮-序列化器 """ class Meta: - model = RoleMenuButtonPermission + model = RoleApiPermission fields = "__all__" read_only_fields = ["id"] -class RoleMenuButtonPermissionCreateUpdateSerializer(CustomModelSerializer): +class RoleApiPermissionCreateUpdateSerializer(CustomModelSerializer): """ 初始化菜单按钮-序列化器 """ @@ -37,7 +37,7 @@ class RoleMenuButtonPermissionCreateUpdateSerializer(CustomModelSerializer): menu_button__value = serializers.CharField(source='menu_button.value', read_only=True) class Meta: - model = RoleMenuButtonPermission + model = RoleApiPermission fields = "__all__" read_only_fields = ["id"] @@ -51,14 +51,14 @@ class RoleButtonPermissionSerializer(CustomModelSerializer): def get_isCheck(self, instance): params = self.request.query_params - return RoleMenuButtonPermission.objects.filter( + return RoleApiPermission.objects.filter( menu_button__id=instance['id'], role__id=params.get('role'), ).exists() def get_data_range(self, instance): params = self.request.query_params - obj = RoleMenuButtonPermission.objects.filter( + obj = RoleApiPermission.objects.filter( menu_button__id=instance['id'], role__id=params.get('role'), ).first() @@ -110,7 +110,7 @@ class RoleMenuPermissionSerializer(CustomModelSerializer): model = Menu fields = ['id','name','isCheck','btns','columns'] -class RoleMenuButtonPermissionViewSet(CustomModelViewSet): +class RoleApiPermissionViewSet(CustomModelViewSet): """ 菜单按钮接口 list:查询 @@ -119,81 +119,12 @@ class RoleMenuButtonPermissionViewSet(CustomModelViewSet): retrieve:单例 destroy:删除 """ - queryset = RoleMenuButtonPermission.objects.all() - serializer_class = RoleMenuButtonPermissionSerializer - create_serializer_class = RoleMenuButtonPermissionCreateUpdateSerializer - update_serializer_class = RoleMenuButtonPermissionCreateUpdateSerializer + queryset = RoleApiPermission.objects.all() + serializer_class = RoleApiPermissionSerializer + create_serializer_class = RoleApiPermissionCreateUpdateSerializer + update_serializer_class = RoleApiPermissionCreateUpdateSerializer extra_filter_class = [] - @action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated]) - def get_role_premission(self, request): - """ - 角色授权获取: - :param request: role - :return: menu,btns,columns - """ - params = request.query_params - role = params.get('role',None) - if role is None: - return ErrorResponse(msg="未获取到角色信息") - is_superuser = request.user.is_superuser - if is_superuser: - queryset = Menu.objects.filter(status=1,is_catalog=False).values('name', 'id').all() - else: - role_id = request.user.role.values_list('id', flat=True) - menu_list = RoleMenuPermission.objects.filter(role__in=role_id).values_list('id',flat=True) - queryset = Menu.objects.filter(status=1, is_catalog=False,id__in=menu_list).values('name', 'id').all() - serializer = RoleMenuPermissionSerializer(queryset,many=True,request=request) - data = serializer.data - return DetailResponse(data=data) - - @action(methods=['PUT'], detail=True, permission_classes=[IsAuthenticated]) - def set_role_premission(self,request,pk): - """ - 对角色的菜单和按钮及按钮范围授权: - :param request: - :param pk: role - :return: - """ - body = request.data - RoleMenuPermission.objects.filter(role=pk).delete() - RoleMenuButtonPermission.objects.filter(role=pk).delete() - for menu in body: - if menu.get('isCheck'): - menu_parent = Menu.objects.filter(id=menu.get('id')).values('parent').first() - RoleMenuPermission.objects.create(role_id=pk, menu_id=menu_parent.get('parent')) - RoleMenuPermission.objects.create(role_id=pk, menu_id=menu.get('id')) - for btn in menu.get('btns'): - if btn.get('isCheck'): - instance = RoleMenuButtonPermission.objects.create(role_id=pk, menu_button_id=btn.get('id'),data_range=btn.get('data_range')) - instance.dept.set(btn.get('dept',[])) - for col in menu.get('columns'): - Columns.objects.filter(id=col.get('id')).update(is_query=col.get('is_query'),is_create=col.get('is_create'),is_update=col.get('is_update')) - return DetailResponse(msg="授权成功") - - - - @action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated]) - def role_menu_get_button(self, request): - """ - 当前用户角色和菜单获取可下拉选项的按钮:角色授权页面使用 - :param request: - :return: - """ - if params := request.query_params: - if menu_id := params.get('menu', None): - is_superuser = request.user.is_superuser - is_admin = request.user.role.values_list('admin', flat=True) - if is_superuser or True in is_admin: - queryset = MenuButton.objects.filter(menu=menu_id).values('id', 'name') - else: - role_list = request.user.role.values_list('id', flat=True) - queryset = RoleMenuButtonPermission.objects.filter( - role__in=role_list, menu_button__menu=menu_id - ).values(btn_id=F('menu_button__id'), name=F('menu_button__name')) - return DetailResponse(data=queryset) - return ErrorResponse(msg="参数错误") - @action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated]) def data_scope(self, request): """ @@ -231,7 +162,7 @@ class RoleMenuButtonPermissionViewSet(CustomModelViewSet): role_list = request.user.role.values_list('id', flat=True) if params := request.query_params: if menu_button_id := params.get('menu_button', None): - role_queryset = RoleMenuButtonPermission.objects.filter( + role_queryset = RoleApiPermission.objects.filter( role__in=role_list, menu_button__id=menu_button_id ).values_list('data_range', flat=True) data_range_list = list(set(role_queryset)) @@ -304,62 +235,6 @@ class RoleMenuButtonPermissionViewSet(CustomModelViewSet): if menu_button is None: return ErrorResponse(msg="参数错误") role_list = request.user.role.values_list('id', flat=True) - queryset = RoleMenuButtonPermission.objects.filter(role__in=role_list, menu_button=None).values( - dept_id=F('dept__id'), - name=F('dept__name'), - parent=F('dept__parent') - ) - return DetailResponse(data=queryset) - - @action(methods=['get'], detail=False, permission_classes=[IsAuthenticated]) - def menu_to_button(self, request): - """ - 根据所选择菜单获取已配置的按钮/接口权限:角色授权页面使用 - :param request: - :return: - """ - params = request.query_params - menu_id = params.get('menu', None) - if menu_id is None: - return ErrorResponse(msg="未获取到参数") - is_superuser = request.user.is_superuser - is_admin = request.user.role.values_list('admin', flat=True) - if is_superuser or True in is_admin: - queryset = RoleMenuButtonPermission.objects.filter(menu_button__menu=menu_id).values( - 'id', - 'data_range', - 'menu_button', - 'menu_button__name', - 'menu_button__value' - ) - return DetailResponse(data=queryset) - else: - if params: - - role_id = params.get('role', None) - if role_id is None: - return ErrorResponse(msg="未获取到参数") - queryset = RoleMenuButtonPermission.objects.filter(role=role_id, menu_button__menu=menu_id).values( - 'id', - 'data_range', - 'menu_button', - 'menu_button__name', - 'menu_button__value' - ) - return DetailResponse(data=queryset) - return ErrorResponse(msg="未获取到参数") - - @action(methods=['get'], detail=False, permission_classes=[IsAuthenticated]) - def role_to_menu(self, request): - """ - 获取角色对应的按钮权限 - :param request: - :return: - """ - params = request.query_params - role_id = params.get('role', None) - if role_id is None: - return ErrorResponse(msg="未获取到参数") - queryset = RoleMenuPermission.objects.filter(role_id=role_id).values_list('menu_id', flat=True).distinct() - + dept_ids = RoleApiPermission.objects.filter(role__in=role_list).values_list('dept__id',flat=True) + queryset = Dept.objects.filter(id__in=dept_ids).values('id', 'name', 'parent') return DetailResponse(data=queryset) diff --git a/backend/dvadmin/system/views/role_menu.py b/backend/dvadmin/system/views/role_menu.py index a74248f..9756d34 100644 --- a/backend/dvadmin/system/views/role_menu.py +++ b/backend/dvadmin/system/views/role_menu.py @@ -78,7 +78,7 @@ class RoleMenuPermissionViewSet(CustomModelViewSet): @action(methods=['get'],detail=False) def get_menu_permission_checked(self,request): """ - 获取已授权的菜单 + 获取已授权的菜单ID """ params = request.query_params role_id = params.get('role',None) diff --git a/backend/dvadmin/utils/filters.py b/backend/dvadmin/utils/filters.py index dbd921f..2241137 100644 --- a/backend/dvadmin/utils/filters.py +++ b/backend/dvadmin/utils/filters.py @@ -20,7 +20,7 @@ from django_filters.rest_framework import DjangoFilterBackend from django_filters.utils import get_model_field from rest_framework.filters import BaseFilterBackend -from dvadmin.system.models import Dept, ApiWhiteList, RoleMenuButtonPermission +from dvadmin.system.models import Dept, ApiWhiteList, RoleApiPermission def get_dept(dept_id: int, dept_all_list=None, dept_list=None): @@ -116,18 +116,17 @@ class DataLevelPermissionsFilter(BaseFilterBackend): if _pk: # 判断是否是单例查询 re_api = re.sub(_pk,'{id}', api) role_id_list = request.user.role.values_list('id', flat=True) - role_permission_list=RoleMenuButtonPermission.objects.filter( + role_permission_list=RoleApiPermission.objects.filter( role__in=role_id_list, role__status=1, - menu_button__api=re_api, - menu_button__method=method).values( + api=re_api, + method=method).values( 'data_range', - role_admin=F('role__admin') ) dataScope_list = [] # 权限范围列表 for ele in role_permission_list: # 判断用户是否为超级管理员角色/如果拥有[全部数据权限]则返回所有数据 - if ele.get("data_range") == 3 or ele.get("role_admin") == True: + if ele.get("data_range") == 3: return queryset dataScope_list.append(ele.get("data_range")) dataScope_list = list(set(dataScope_list)) diff --git a/backend/dvadmin/utils/permission.py b/backend/dvadmin/utils/permission.py index 8716264..1c00313 100644 --- a/backend/dvadmin/utils/permission.py +++ b/backend/dvadmin/utils/permission.py @@ -12,7 +12,7 @@ from django.contrib.auth.models import AnonymousUser from django.db.models import F from rest_framework.permissions import BasePermission -from dvadmin.system.models import ApiWhiteList, RoleMenuButtonPermission +from dvadmin.system.models import ApiWhiteList, RoleApiPermission def ValidationApi(reqApi, validApi): @@ -74,18 +74,18 @@ class CustomPermission(BasePermission): methodList = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH'] method = methodList.index(method) # ***接口白名单*** - api_white_list = ApiWhiteList.objects.values(permission__api=F('url'), permission__method=F('method')) + api_white_list = ApiWhiteList.objects.values('method',api=F('url')) api_white_list = [ - str(item.get('permission__api').replace('{id}', '([a-zA-Z0-9-]+)')) + ":" + str( - item.get('permission__method')) + '$' for item in api_white_list if item.get('permission__api')] + str(item.get('api').replace('{id}', '([a-zA-Z0-9-]+)')) + ":" + str( + item.get('method')) + '$' for item in api_white_list if item.get('api')] # ********# if not hasattr(request.user, "role"): return False role_id_list = request.user.role.values_list('id',flat=True) - userApiList = RoleMenuButtonPermission.objects.filter(role__in=role_id_list).values(permission__api=F('menu_button__api'), permission__method=F('menu_button__method')) # 获取当前用户的角色拥有的所有接口 + userApiList = RoleApiPermission.objects.filter(role__in=role_id_list).values('api','method') # 获取当前用户的角色拥有的所有接口 ApiList = [ - str(item.get('permission__api').replace('{id}', '([a-zA-Z0-9-]+)')) + ":" + str( - item.get('permission__method')) + '$' for item in userApiList if item.get('permission__api')] + str(item.get('api').replace('{id}', '([a-zA-Z0-9-]+)')) + ":" + str( + item.get('method')) + '$' for item in userApiList if item.get('api')] new_api_ist = api_white_list + ApiList new_api = api + ":" + str(method) for item in new_api_ist: diff --git a/web/src/plugin/permission/store.permission.ts b/web/src/plugin/permission/store.permission.ts index 2879628..f2fdeda 100644 --- a/web/src/plugin/permission/store.permission.ts +++ b/web/src/plugin/permission/store.permission.ts @@ -9,7 +9,7 @@ export const BtnPermissionStore = defineStore('BtnPermission', { actions: { async getBtnPermissionStore() { request({ - url: '/api/system/menu_button/menu_button_all_permission/', + url: '/api/system/menu/menu_button_all_permission/', method: 'get', }).then((ret: { data: [] diff --git a/web/src/views/system/role/components/ApiPermission/api.ts b/web/src/views/system/role/components/ApiPermission/api.ts new file mode 100644 index 0000000..f1a0ded --- /dev/null +++ b/web/src/views/system/role/components/ApiPermission/api.ts @@ -0,0 +1,57 @@ +import { request } from '/@/utils/service'; +import { UserPageQuery, AddReq, DelReq, EditReq, InfoReq } from '@fast-crud/fast-crud'; +import XEUtils from "xe-utils"; + +export const apiPrefix = '/api/system/role_api_permission/'; +export function GetList(query: UserPageQuery) { + return request({ + url: apiPrefix, + method: 'get', + params: query, + }); +} +export function GetObj(id: InfoReq) { + return request({ + url: apiPrefix + id, + method: 'get', + }); +} + +export function AddObj(obj: AddReq) { + return request({ + url: apiPrefix, + method: 'post', + data: obj, + }); +} + +export function UpdateObj(obj: EditReq) { + return request({ + url: apiPrefix + obj.id + '/', + method: 'put', + data: obj, + }); +} + +export function DelObj(id: DelReq) { + return request({ + url: apiPrefix + id + '/', + method: 'delete', + data: { id }, + }); +} + +/** + * 获取数据范围授权的所有部门 + * @param query + * @constructor + */ +export function GetAllDeptData(query: UserPageQuery) { + return request({ + url: apiPrefix+'role_to_dept_all/', + method: 'get', + params: query, + }).then((res:any)=>{ + return XEUtils.toArrayTree(res.data,{ parentKey: 'parent', key: 'id', children: 'children',}) + }) +} diff --git a/web/src/views/system/role/components/ApiPermission/crud.tsx b/web/src/views/system/role/components/ApiPermission/crud.tsx new file mode 100644 index 0000000..cc04c7c --- /dev/null +++ b/web/src/views/system/role/components/ApiPermission/crud.tsx @@ -0,0 +1,207 @@ +import * as api from './api'; +import { dict, UserPageQuery, AddReq, DelReq, EditReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet } from '@fast-crud/fast-crud'; +import { request } from '/@/utils/service'; +import { dictionary } from '/@/utils/dictionary'; +import { successMessage } from '/@/utils/message'; +import {inject} from "vue"; + +export const createCrudOptions = function ({ crudExpose,propsContext }: CreateCrudOptionsProps): CreateCrudOptionsRet { + const pageRequest = async (query: UserPageQuery) => { + return await api.GetList(query); + }; + const editRequest = async ({ form, row }: EditReq) => { + form.id = row.id; + return await api.UpdateObj(form); + }; + const delRequest = async ({ row }: DelReq) => { + return await api.DelObj(row.id); + }; + const addRequest = async ({ form }: AddReq) => { + form.role = propsContext.roleId + return await api.AddObj(form); + }; + + //权限判定 + const hasPermissions = inject("$hasPermissions") + + return { + crudOptions: { + request: { + pageRequest, + addRequest, + editRequest, + delRequest, + }, + rowHandle: { + //固定右侧 + fixed: 'right', + }, + form: { + col: { span: 24 }, + labelWidth: '110px', + wrapper: { + is: 'el-dialog', + width: '600px', + }, + }, + columns: { + _index: { + title: '序号', + form: { show: false }, + column: { + //type: 'index', + align: 'center', + width: '70px', + columnSetDisabled: true, //禁止在列设置中选择 + //@ts-ignore + formatter: (context) => { + //计算序号,你可以自定义计算规则,此处为翻页累加 + let index = context.index ?? 1; + let pagination: any = crudExpose!.crudBinding.value.pagination; + return ((pagination.currentPage ?? 1) - 1) * pagination.pageSize + index + 1; + }, + }, + }, + name:{ + title: '接口名称', + type: 'text', + search:{ + show:true + }, + column:{ + width:150 + } + }, + method: { + title: '请求方式', + sortable: 'custom', + search: { + show:true + }, + type: 'dict-select', + dict: dict({ + data: [ + { + label: 'GET', + value: 0, + }, + { + label: 'POST', + value: 1, + }, + { + label: 'PUT', + value: 2, + }, + { + label: 'DELETE', + value: 3, + }, + { + label: 'PATCH', + value: 4, + }, + ], + }), + column:{ + width: 100, + }, + form: { + rules: [ + // 表单校验规则 + { + required: true, + message: '必填项', + }, + ], + component: { + span: 12, + }, + }, + }, + api: { + title: '接口地址', + sortable: 'custom', + search: { + disabled: true, + }, + type: 'dict-select', + dict: dict({ + async getData(dict: any) { + return request('/swagger.json').then((ret: any) => { + const res = Object.keys(ret.paths); + const data = []; + for (const item of res) { + const obj = { label: '', value: '' }; + obj.label = item; + obj.value = item; + data.push(obj); + } + return data; + }); + }, + }), + column:{ + minWidth: 200, + }, + form: { + rules: [ + // 表单校验规则 + { + required: true, + message: '必填项', + }, + ], + component: { + span: 24, + props: { + allowCreate: true, + filterable: true, + clearable: true, + }, + }, + helper: { + position: 'label', + tooltip: { + placement: 'top-start', + }, + text: '请正确填写,以免请求时被拦截。匹配单例使用正则,例如:/api/xx/.*?/', + }, + }, + }, + data_range: { + title: '数据权限范围', + search: { + show:true + }, + type: 'dict-select', + dict:dict({ + url:'/api/system/role_api_permission/data_scope/' + }), + column: { + minWidth:120, + }, + + }, + dept:{ + title:'数据权限部门', + column:{ + minWidth:120, + }, + form:{ + show: compute(({form})=>{ + return form.data_range===4 + }) + } + }, + description:{ + title:'描述', + type:'textarea', + column:{ + width:300 + } + } + }, + }, + }; +}; diff --git a/web/src/views/system/role/components/ApiPermission/index.vue b/web/src/views/system/role/components/ApiPermission/index.vue new file mode 100644 index 0000000..2becc5d --- /dev/null +++ b/web/src/views/system/role/components/ApiPermission/index.vue @@ -0,0 +1,59 @@ + + + + + diff --git a/web/src/views/system/role/components/index.vue b/web/src/views/system/role/components/index.vue index 03fb0b9..5f123a1 100644 --- a/web/src/views/system/role/components/index.vue +++ b/web/src/views/system/role/components/index.vue @@ -1,5 +1,7 @@