1.完成新版接口授权

This commit is contained in:
猿小天
2023-10-29 00:33:07 +08:00
parent b7b589176a
commit 10b159aa15
16 changed files with 402 additions and 312 deletions

View File

@@ -252,7 +252,7 @@ class RoleMenuPermission(CoreModel):
# ordering = ("-create_datetime",) # ordering = ("-create_datetime",)
class RoleMenuButtonPermission(CoreModel): class RoleApiPermission(CoreModel):
role = models.ForeignKey( role = models.ForeignKey(
to="Role", to="Role",
db_constraint=False, db_constraint=False,
@@ -261,16 +261,16 @@ class RoleMenuButtonPermission(CoreModel):
verbose_name="关联角色", verbose_name="关联角色",
help_text="关联角色", help_text="关联角色",
) )
menu_button = models.ForeignKey( name = models.CharField(max_length=64, verbose_name="名称", help_text="名称")
to="MenuButton", api = models.CharField(max_length=200, verbose_name="接口地址", help_text="接口地址")
db_constraint=False, METHOD_CHOICES = (
related_name="menu_button_permission", (0, "GET"),
on_delete=models.CASCADE, (1, "POST"),
verbose_name="关联菜单按钮", (2, "PUT"),
help_text="关联菜单按钮", (3, "DELETE"),
null=True,
blank=True
) )
method = models.IntegerField(default=0, verbose_name="接口请求方法", null=True, blank=True,
help_text="接口请求方法")
DATASCOPE_CHOICES = ( DATASCOPE_CHOICES = (
(0, "仅本人数据权限"), (0, "仅本人数据权限"),
(1, "本部门及以下数据权限"), (1, "本部门及以下数据权限"),
@@ -284,8 +284,8 @@ class RoleMenuButtonPermission(CoreModel):
help_text="数据权限-关联部门") help_text="数据权限-关联部门")
class Meta: class Meta:
db_table = table_prefix + "role_menu_button_permission" db_table = table_prefix + "role_api_permission"
verbose_name = "角色按钮权限表" verbose_name = "角色接口权限表"
verbose_name_plural = verbose_name verbose_name_plural = verbose_name
ordering = ("-create_datetime",) ordering = ("-create_datetime",)

View File

@@ -8,19 +8,17 @@ from dvadmin.system.views.dictionary import DictionaryViewSet
from dvadmin.system.views.file_list import FileViewSet from dvadmin.system.views.file_list import FileViewSet
from dvadmin.system.views.login_log import LoginLogViewSet from dvadmin.system.views.login_log import LoginLogViewSet
from dvadmin.system.views.menu import MenuViewSet 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.message_center import MessageCenterViewSet
from dvadmin.system.views.operation_log import OperationLogViewSet from dvadmin.system.views.operation_log import OperationLogViewSet
from dvadmin.system.views.role import RoleViewSet from dvadmin.system.views.role import RoleViewSet
from dvadmin.system.views.role_menu import RoleMenuPermissionViewSet 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.system_config import SystemConfigViewSet
from dvadmin.system.views.user import UserViewSet from dvadmin.system.views.user import UserViewSet
from dvadmin.system.views.column import ColumnViewSet from dvadmin.system.views.column import ColumnViewSet
system_url = routers.SimpleRouter() system_url = routers.SimpleRouter()
system_url.register(r'menu', MenuViewSet) system_url.register(r'menu', MenuViewSet)
system_url.register(r'menu_button', MenuButtonViewSet)
system_url.register(r'role', RoleViewSet) system_url.register(r'role', RoleViewSet)
system_url.register(r'dept', DeptViewSet) system_url.register(r'dept', DeptViewSet)
system_url.register(r'user', UserViewSet) 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'api_white_list', ApiWhiteListViewSet)
system_url.register(r'system_config', SystemConfigViewSet) system_url.register(r'system_config', SystemConfigViewSet)
system_url.register(r'message_center', MessageCenterViewSet) 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'role_menu_permission', RoleMenuPermissionViewSet)
system_url.register(r'column', ColumnViewSet) system_url.register(r'column', ColumnViewSet)

View File

@@ -9,7 +9,7 @@ from rest_framework import serializers
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated 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.json_response import DetailResponse, SuccessResponse, ErrorResponse
from dvadmin.utils.serializers import CustomModelSerializer from dvadmin.utils.serializers import CustomModelSerializer
from dvadmin.utils.viewset import CustomModelViewSet from dvadmin.utils.viewset import CustomModelViewSet
@@ -135,7 +135,7 @@ class DeptViewSet(CustomModelViewSet):
queryset = Dept.objects.values('id', 'name', 'parent') queryset = Dept.objects.values('id', 'name', 'parent')
else: else:
role_ids = request.user.role.values_list('id', flat=True) 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 user_dept_id = request.user.dept.id
dept_list = [user_dept_id] dept_list = [user_dept_id]
data_range_list = list(set(data_range)) data_range_list = list(set(data_range))

View File

@@ -8,9 +8,9 @@
""" """
from rest_framework import serializers from rest_framework import serializers
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated
from dvadmin.system.models import Menu, RoleMenuPermission 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.json_response import SuccessResponse, ErrorResponse, DetailResponse
from dvadmin.utils.serializers import CustomModelSerializer from dvadmin.utils.serializers import CustomModelSerializer
from dvadmin.utils.viewset import CustomModelViewSet from dvadmin.utils.viewset import CustomModelViewSet
@@ -104,6 +104,9 @@ class MenuViewSet(CustomModelViewSet):
@action(methods=['get'], detail=True) @action(methods=['get'], detail=True)
def getChildren(self,request,pk): def getChildren(self,request,pk):
"""
获取子菜单,用于菜单页面的懒加载
"""
queryset = Menu.objects.filter(parent=pk) queryset = Menu.objects.filter(parent=pk)
serializer = MenuSerializer(queryset, many=True, request=request) serializer = MenuSerializer(queryset, many=True, request=request)
data = serializer.data data = serializer.data
@@ -113,17 +116,31 @@ class MenuViewSet(CustomModelViewSet):
def web_router(self, request): def web_router(self, request):
"""用于前端获取当前角色的路由""" """用于前端获取当前角色的路由"""
user = request.user user = request.user
is_admin = user.role.values_list('admin', flat=True)
if user.is_superuser: if user.is_superuser:
queryset = self.queryset.filter(status=1) queryset = self.queryset.filter(status=1)
else: else:
role_list = user.role.values_list('id', flat=True) role_list = user.role.values_list('id', flat=True)
menu_list = RoleMenuPermission.objects.filter(role__in=role_list).values_list('menu_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) serializer = WebRouterSerializer(queryset, many=True, request=request)
data = serializer.data data = serializer.data
return SuccessResponse(data=data, total=len(data), msg="获取成功") 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=[]) @action(methods=['GET'], detail=False, permission_classes=[])
def get_all_menu(self, request): def get_all_menu(self, request):
"""用于菜单管理获取所有的菜单""" """用于菜单管理获取所有的菜单"""

View File

@@ -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)

View File

@@ -13,7 +13,6 @@ from rest_framework.permissions import IsAuthenticated
from dvadmin.system.models import Role, Menu, MenuButton, Dept from dvadmin.system.models import Role, Menu, MenuButton, Dept
from dvadmin.system.views.dept import DeptSerializer from dvadmin.system.views.dept import DeptSerializer
from dvadmin.system.views.menu import MenuSerializer 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.crud_mixin import FastCrudMixin
from dvadmin.utils.field_permission import FieldPermissionMixin from dvadmin.utils.field_permission import FieldPermissionMixin
from dvadmin.utils.json_response import SuccessResponse, DetailResponse from dvadmin.utils.json_response import SuccessResponse, DetailResponse
@@ -39,7 +38,6 @@ class RoleCreateUpdateSerializer(CustomModelSerializer):
""" """
menu = MenuSerializer(many=True, read_only=True) menu = MenuSerializer(many=True, read_only=True)
dept = DeptSerializer(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, key = serializers.CharField(max_length=50,
validators=[CustomUniqueValidator(queryset=Role.objects.all(), message="权限字符必须唯一")]) validators=[CustomUniqueValidator(queryset=Role.objects.all(), message="权限字符必须唯一")])
name = serializers.CharField(max_length=50, validators=[CustomUniqueValidator(queryset=Role.objects.all())]) 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: class Meta:
model = Menu model = Menu
fields = ['id', 'parent', 'name', 'menuPermission'] fields = ['id', 'parent', 'name']
class MenuButtonPermissionSerializer(CustomModelSerializer): class MenuButtonPermissionSerializer(CustomModelSerializer):

View File

@@ -11,25 +11,25 @@ from rest_framework import serializers
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated 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.system.views.menu import MenuSerializer
from dvadmin.utils.json_response import DetailResponse, ErrorResponse from dvadmin.utils.json_response import DetailResponse, ErrorResponse
from dvadmin.utils.serializers import CustomModelSerializer from dvadmin.utils.serializers import CustomModelSerializer
from dvadmin.utils.viewset import CustomModelViewSet from dvadmin.utils.viewset import CustomModelViewSet
class RoleMenuButtonPermissionSerializer(CustomModelSerializer): class RoleApiPermissionSerializer(CustomModelSerializer):
""" """
菜单按钮-序列化器 菜单按钮-序列化器
""" """
class Meta: class Meta:
model = RoleMenuButtonPermission model = RoleApiPermission
fields = "__all__" fields = "__all__"
read_only_fields = ["id"] 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) menu_button__value = serializers.CharField(source='menu_button.value', read_only=True)
class Meta: class Meta:
model = RoleMenuButtonPermission model = RoleApiPermission
fields = "__all__" fields = "__all__"
read_only_fields = ["id"] read_only_fields = ["id"]
@@ -51,14 +51,14 @@ class RoleButtonPermissionSerializer(CustomModelSerializer):
def get_isCheck(self, instance): def get_isCheck(self, instance):
params = self.request.query_params params = self.request.query_params
return RoleMenuButtonPermission.objects.filter( return RoleApiPermission.objects.filter(
menu_button__id=instance['id'], menu_button__id=instance['id'],
role__id=params.get('role'), role__id=params.get('role'),
).exists() ).exists()
def get_data_range(self, instance): def get_data_range(self, instance):
params = self.request.query_params params = self.request.query_params
obj = RoleMenuButtonPermission.objects.filter( obj = RoleApiPermission.objects.filter(
menu_button__id=instance['id'], menu_button__id=instance['id'],
role__id=params.get('role'), role__id=params.get('role'),
).first() ).first()
@@ -110,7 +110,7 @@ class RoleMenuPermissionSerializer(CustomModelSerializer):
model = Menu model = Menu
fields = ['id','name','isCheck','btns','columns'] fields = ['id','name','isCheck','btns','columns']
class RoleMenuButtonPermissionViewSet(CustomModelViewSet): class RoleApiPermissionViewSet(CustomModelViewSet):
""" """
菜单按钮接口 菜单按钮接口
list:查询 list:查询
@@ -119,81 +119,12 @@ class RoleMenuButtonPermissionViewSet(CustomModelViewSet):
retrieve:单例 retrieve:单例
destroy:删除 destroy:删除
""" """
queryset = RoleMenuButtonPermission.objects.all() queryset = RoleApiPermission.objects.all()
serializer_class = RoleMenuButtonPermissionSerializer serializer_class = RoleApiPermissionSerializer
create_serializer_class = RoleMenuButtonPermissionCreateUpdateSerializer create_serializer_class = RoleApiPermissionCreateUpdateSerializer
update_serializer_class = RoleMenuButtonPermissionCreateUpdateSerializer update_serializer_class = RoleApiPermissionCreateUpdateSerializer
extra_filter_class = [] 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]) @action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated])
def data_scope(self, request): def data_scope(self, request):
""" """
@@ -231,7 +162,7 @@ class RoleMenuButtonPermissionViewSet(CustomModelViewSet):
role_list = request.user.role.values_list('id', flat=True) role_list = request.user.role.values_list('id', flat=True)
if params := request.query_params: if params := request.query_params:
if menu_button_id := params.get('menu_button', None): 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 role__in=role_list, menu_button__id=menu_button_id
).values_list('data_range', flat=True) ).values_list('data_range', flat=True)
data_range_list = list(set(role_queryset)) data_range_list = list(set(role_queryset))
@@ -304,62 +235,6 @@ class RoleMenuButtonPermissionViewSet(CustomModelViewSet):
if menu_button is None: if menu_button is None:
return ErrorResponse(msg="参数错误") return ErrorResponse(msg="参数错误")
role_list = request.user.role.values_list('id', flat=True) role_list = request.user.role.values_list('id', flat=True)
queryset = RoleMenuButtonPermission.objects.filter(role__in=role_list, menu_button=None).values( dept_ids = RoleApiPermission.objects.filter(role__in=role_list).values_list('dept__id',flat=True)
dept_id=F('dept__id'), queryset = Dept.objects.filter(id__in=dept_ids).values('id', 'name', 'parent')
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()
return DetailResponse(data=queryset) return DetailResponse(data=queryset)

View File

@@ -78,7 +78,7 @@ class RoleMenuPermissionViewSet(CustomModelViewSet):
@action(methods=['get'],detail=False) @action(methods=['get'],detail=False)
def get_menu_permission_checked(self,request): def get_menu_permission_checked(self,request):
""" """
获取已授权的菜单 获取已授权的菜单ID
""" """
params = request.query_params params = request.query_params
role_id = params.get('role',None) role_id = params.get('role',None)

View File

@@ -20,7 +20,7 @@ from django_filters.rest_framework import DjangoFilterBackend
from django_filters.utils import get_model_field from django_filters.utils import get_model_field
from rest_framework.filters import BaseFilterBackend 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): def get_dept(dept_id: int, dept_all_list=None, dept_list=None):
@@ -116,18 +116,17 @@ class DataLevelPermissionsFilter(BaseFilterBackend):
if _pk: # 判断是否是单例查询 if _pk: # 判断是否是单例查询
re_api = re.sub(_pk,'{id}', api) re_api = re.sub(_pk,'{id}', api)
role_id_list = request.user.role.values_list('id', flat=True) 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__in=role_id_list,
role__status=1, role__status=1,
menu_button__api=re_api, api=re_api,
menu_button__method=method).values( method=method).values(
'data_range', 'data_range',
role_admin=F('role__admin')
) )
dataScope_list = [] # 权限范围列表 dataScope_list = [] # 权限范围列表
for ele in role_permission_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 return queryset
dataScope_list.append(ele.get("data_range")) dataScope_list.append(ele.get("data_range"))
dataScope_list = list(set(dataScope_list)) dataScope_list = list(set(dataScope_list))

View File

@@ -12,7 +12,7 @@ from django.contrib.auth.models import AnonymousUser
from django.db.models import F from django.db.models import F
from rest_framework.permissions import BasePermission from rest_framework.permissions import BasePermission
from dvadmin.system.models import ApiWhiteList, RoleMenuButtonPermission from dvadmin.system.models import ApiWhiteList, RoleApiPermission
def ValidationApi(reqApi, validApi): def ValidationApi(reqApi, validApi):
@@ -74,18 +74,18 @@ class CustomPermission(BasePermission):
methodList = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH'] methodList = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH']
method = methodList.index(method) 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 = [ api_white_list = [
str(item.get('permission__api').replace('{id}', '([a-zA-Z0-9-]+)')) + ":" + str( str(item.get('api').replace('{id}', '([a-zA-Z0-9-]+)')) + ":" + str(
item.get('permission__method')) + '$' for item in api_white_list if item.get('permission__api')] item.get('method')) + '$' for item in api_white_list if item.get('api')]
# ********# # ********#
if not hasattr(request.user, "role"): if not hasattr(request.user, "role"):
return False return False
role_id_list = request.user.role.values_list('id',flat=True) 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 = [ ApiList = [
str(item.get('permission__api').replace('{id}', '([a-zA-Z0-9-]+)')) + ":" + str( str(item.get('api').replace('{id}', '([a-zA-Z0-9-]+)')) + ":" + str(
item.get('permission__method')) + '$' for item in userApiList if item.get('permission__api')] item.get('method')) + '$' for item in userApiList if item.get('api')]
new_api_ist = api_white_list + ApiList new_api_ist = api_white_list + ApiList
new_api = api + ":" + str(method) new_api = api + ":" + str(method)
for item in new_api_ist: for item in new_api_ist:

View File

@@ -9,7 +9,7 @@ export const BtnPermissionStore = defineStore('BtnPermission', {
actions: { actions: {
async getBtnPermissionStore() { async getBtnPermissionStore() {
request({ request({
url: '/api/system/menu_button/menu_button_all_permission/', url: '/api/system/menu/menu_button_all_permission/',
method: 'get', method: 'get',
}).then((ret: { }).then((ret: {
data: [] data: []

View File

@@ -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',})
})
}

View File

@@ -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
}
}
},
},
};
};

View File

@@ -0,0 +1,59 @@
<template>
<div style="height: 86vh">
<fs-crud ref="crudRef" v-bind="crudBinding">
<template #form_dept="scope">
<div>
<el-tree-select
v-model="scope.form.dept"
:data="allDeptData"
:props="treeProps"
node-key="id"
multiple
:render-after-expand="false"
show-checkbox
check-strictly
check-on-click-node
>
<template #default="{ data: { name } }">
{{ name }}
</template
>
</el-tree-select>
</div>
</template>
</fs-crud>
</div>
</template>
<script lang="ts" setup>
import {ref, onMounted, reactive} from 'vue';
import {useFs} from '@fast-crud/fast-crud';
import {createCrudOptions} from './crud';
import {GetAllDeptData} from './api'
const propsContext = defineProps({
roleId:{
type:String||Number,
required:true
}
})
const {crudBinding, crudRef, crudExpose} = useFs({createCrudOptions,propsContext});
// 获取所有部门数据
const allDeptData = ref<any[]>([]);
const treeProps ={
label: 'name',
value: 'id',
children: 'children',
}
onMounted(async () => {
const res = await GetAllDeptData({role:propsContext.roleId});
allDeptData.value = res;
crudExpose.doSearch({form:{role:propsContext.roleId}})
});
</script>
<style scoped>
</style>

View File

@@ -1,5 +1,7 @@
<template> <template>
<el-drawer v-model="drawerVisible" title="权限配置" direction="rtl" size="60%" :close-on-click-modal="false" <el-drawer v-model="drawerVisible" title="权限配置" direction="rtl" size="60%"
:close-on-click-modal="false"
destroy-on-close
:before-close="handleDrawerClose"> :before-close="handleDrawerClose">
<template #header> <template #header>
<el-row> <el-row>
@@ -11,12 +13,14 @@
</el-row> </el-row>
</template> </template>
<div> <div>
<el-tabs type="border-card"> <el-tabs type="border-card" v-model="permissionTab">
<el-tab-pane label="菜单/按钮授权"> <el-tab-pane label="菜单/按钮授权" name="menu">
<MenuPermission ref="menuPermissionRef" :role-id="props.roleId" @handleDrawerClose="handleDrawerClose"></MenuPermission> <MenuPermission ref="menuPermissionRef" :role-id="props.roleId" @handleDrawerClose="handleDrawerClose"></MenuPermission>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="请求接口授权"></el-tab-pane> <el-tab-pane label="请求接口授权" name="api">
<el-tab-pane label="接口权限">角色管理</el-tab-pane> <ApiPermission :role-id="props.roleId"></ApiPermission>
</el-tab-pane>
<el-tab-pane label="接口权限" name="column">角色管理</el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</el-drawer> </el-drawer>
@@ -28,7 +32,7 @@ import XEUtils from 'xe-utils';
import {errorNotification} from '/@/utils/message'; import {errorNotification} from '/@/utils/message';
import {ElMessage} from 'element-plus' import {ElMessage} from 'element-plus'
import MenuPermission from "./MenuPermission/index.vue"; import MenuPermission from "./MenuPermission/index.vue";
import ApiPermission from "./ApiPermission/index.vue";
const props = defineProps({ const props = defineProps({
roleId: { roleId: {
type: Number, type: Number,
@@ -45,28 +49,24 @@ const props = defineProps({
}) })
const emit = defineEmits(['update:drawerVisible']) const emit = defineEmits(['update:drawerVisible'])
const menuPermissionRef = ref() const menuPermissionRef = ref()
const permissionTab = ref('menu')
const drawerVisible = ref(false) const drawerVisible = ref(false)
watch( watch(
() => props.drawerVisible, () => props.drawerVisible,
(val) => { (val) => {
drawerVisible.value = val; drawerVisible.value = val;
nextTick(()=>{ nextTick(()=>{
console.log(menuPermissionRef)
menuPermissionRef.value.getMenuPremissionTreeData() menuPermissionRef.value.getMenuPremissionTreeData()
}) })
// fetchData() // fetchData()
} }
); );
const handleDrawerClose = () => { const handleDrawerClose = () => {
permissionTab.value ='menu'
emit('update:drawerVisible', false); emit('update:drawerVisible', false);
} }
const defaultTreeProps = {
children: 'children',
label: 'name',
value: 'id',
};
let collapseCurrent = ref(['1']); let collapseCurrent = ref(['1']);

View File

@@ -79,12 +79,8 @@ export const createCrudOptions = function ({
}, */ }, */
customNew: { customNew: {
type: 'primary', type: 'primary',
text: '权限配置', text: '权',
show: hasPermissions('role:Update'), show: hasPermissions('role:Update'),
tooltip: {
placement: 'top',
content: '权限配置',
},
click: (context: any): void => { click: (context: any): void => {
const { row } = context; const { row } = context;
handleDrawerOpen(row); handleDrawerOpen(row);
@@ -183,40 +179,6 @@ export const createCrudOptions = function ({
value: 1, value: 1,
}, },
}, },
admin: {
title: '是否管理员',
search: { show: false },
type: 'dict-radio',
dict: dict({
data: [
{
label: '是',
value: true,
color: 'success',
},
{
label: '否',
value: false,
color: 'danger',
},
],
}),
column: {
minWidth: 130,
sortable: 'custom',
show: columnPermission('admin', 'is_query'),
},
addForm: {
show: columnPermission('admin', 'is_create'),
},
editForm: {
show: columnPermission('admin', 'is_update'),
},
form: {
rules: [{ required: true, message: '是否管理员必填' }],
value: false,
},
},
status: { status: {
title: '状态', title: '状态',
search: { show: true }, search: { show: true },