123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- # -*- coding: utf-8 -*-
- """
- @author: Allen
- @Created on: 2023/10/18
- @Remark: 菜单模块
- """
- from rest_framework import serializers
- from rest_framework.decorators import action
- from dvadmin.system.models import Menu, MenuButton
- from dvadmin.system.views.menu_button import MenuButtonInitSerializer
- from dvadmin.utils.json_response import SuccessResponse
- from dvadmin.utils.serializers import CustomModelSerializer
- from dvadmin.utils.viewset import CustomModelViewSet
- class MenuSerializer(CustomModelSerializer):
- """
- 菜单表的简单序列化器
- """
- menuPermission = serializers.SerializerMethodField(read_only=True)
- hasChild = serializers.SerializerMethodField()
- def get_menuPermission(self, instance):
- queryset = instance.menuPermission.order_by('-name').values_list('name', flat=True)
- if queryset:
- return queryset
- else:
- return None
- def get_hasChild(self, instance):
- hasChild = Menu.objects.filter(parent=instance.id)
- if hasChild:
- return True
- return False
- class Meta:
- model = Menu
- fields = "__all__"
- read_only_fields = ["id"]
- class MenuCreateSerializer(CustomModelSerializer):
- """
- 菜单表的创建序列化器
- """
- name = serializers.CharField(required=False)
- class Meta:
- model = Menu
- fields = "__all__"
- read_only_fields = ["id"]
- class MenuInitSerializer(CustomModelSerializer):
- """
- 递归深度获取数信息(用于生成初始化json文件)
- """
- name = serializers.CharField(required=False)
- children = serializers.SerializerMethodField()
- menu_button = serializers.SerializerMethodField()
- def get_children(self, obj: Menu):
- data = []
- instance = Menu.objects.filter(parent_id=obj.id)
- if instance:
- serializer = MenuInitSerializer(instance=instance, many=True)
- data = serializer.data
- return data
- def get_menu_button(self, obj: Menu):
- data = []
- instance = obj.menuPermission.order_by('method')
- if instance:
- data = list(instance.values('name', 'value', 'api', 'method'))
- return data
- def save(self, **kwargs):
- instance = super().save(**kwargs)
- children = self.initial_data.get('children')
- menu_button = self.initial_data.get('menu_button')
- # 菜单表
- if children:
- for menu_data in children:
- menu_data['parent'] = instance.id
- filter_data = {
- "name": menu_data['name'],
- "web_path": menu_data['web_path'],
- "component": menu_data['component'],
- "component_name": menu_data['component_name'],
- }
- instance_obj = Menu.objects.filter(**filter_data).first()
- if instance_obj and not self.initial_data.get('reset'):
- continue
- serializer = MenuInitSerializer(instance_obj, data=menu_data, request=self.request)
- serializer.is_valid(raise_exception=True)
- serializer.save()
- # 菜单按钮
- if menu_button:
- for menu_button_data in menu_button:
- menu_button_data['menu'] = instance.id
- filter_data = {
- "menu": menu_button_data['menu'],
- "value": menu_button_data['value']
- }
- instance_obj = MenuButton.objects.filter(**filter_data).first()
- serializer = MenuButtonInitSerializer(instance_obj, data=menu_button_data, request=self.request)
- serializer.is_valid(raise_exception=True)
- serializer.save()
- return instance
- class Meta:
- model = Menu
- fields = ['name', 'icon', 'sort', 'is_link', 'is_catalog', 'web_path', 'component', 'component_name', 'status',
- 'cache', 'visible', 'parent', 'children', 'menu_button', 'frame_out', 'creator', 'dept_belong_id']
- extra_kwargs = {
- 'creator': {'write_only': True},
- 'dept_belong_id': {'write_only': True}
- }
- read_only_fields = ['id', 'children']
- class WebRouterSerializer(CustomModelSerializer):
- """
- 前端菜单路由的简单序列化器
- """
- path = serializers.CharField(source="web_path")
- title = serializers.CharField(source="name")
- menuPermission = serializers.SerializerMethodField(read_only=True)
- def get_menuPermission(self, instance):
- # 判断是否是超级管理员
- if self.request.user.is_superuser:
- return instance.menuPermission.values_list('value', flat=True)
- else:
- # 根据当前角色获取权限按钮id集合
- permissionIds = self.request.user.role.values_list('permission', flat=True)
- queryset = instance.menuPermission.filter(id__in=permissionIds, menu=instance.id).values_list('value',
- flat=True)
- if queryset:
- return queryset
- else:
- return None
- class Meta:
- model = Menu
- fields = (
- 'id', 'parent', 'icon', 'sort', 'path', 'name', 'title', 'is_link', 'is_catalog', 'web_path', 'component',
- 'component_name', 'cache', 'visible', 'menuPermission', 'frame_out')
- read_only_fields = ["id"]
- class MenuViewSet(CustomModelViewSet):
- """
- 菜单管理接口
- list:查询
- create:新增
- update:修改
- retrieve:单例
- destroy:删除
- """
- queryset = Menu.objects.all()
- serializer_class = MenuSerializer
- create_serializer_class = MenuCreateSerializer
- update_serializer_class = MenuCreateSerializer
- search_fields = ['name', 'status']
- filter_fields = ['parent', 'name', 'status', 'is_link', 'visible', 'cache', 'is_catalog']
- # extra_filter_backends = []
- @action(methods=['GET'], detail=False, permission_classes=[])
- def web_router(self, request):
- """用于前端获取当前角色的路由"""
- user = request.user
- queryset = self.queryset.filter(status=1)
- if not user.is_superuser:
- menuIds = user.role.values_list('menu__id', flat=True)
- queryset = Menu.objects.filter(id__in=menuIds, status=1)
- serializer = WebRouterSerializer(queryset, many=True, request=request)
- data = serializer.data
- return SuccessResponse(data=data, total=len(data), msg="获取成功")
- def list(self, request):
- """懒加载"""
- params = request.query_params
- parent = params.get('parent', None)
- if params:
- if parent:
- queryset = self.queryset.filter(parent=parent)
- else:
- queryset = self.queryset
- else:
- queryset = self.queryset.filter(parent__isnull=True)
- queryset = self.filter_queryset(queryset)
- serializer = MenuSerializer(queryset, many=True, request=request)
- data = serializer.data
- return SuccessResponse(data=data)
|