# -*- coding: utf-8 -*- """ @author: 猿小天 @contact: QQ:1638245306 @Created on: 2021/6/1 001 22:38 @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 MenuButtonSerializer from dvadmin.utils.json_response import SuccessResponse from dvadmin.utils.serializers import CustomModelSerializer from dvadmin.utils.viewset import CustomModelViewSet class MenuSerializer(CustomModelSerializer): """ 菜单表的简单序列化器 """ parent = serializers.SerializerMethodField(read_only=True) menuPermission = serializers.SerializerMethodField(read_only=True) def get_parent(self, instance): return instance.get_parent().id if instance.get_parent() else None def get_menuPermission(self, instance): queryset = ( MenuButton.objects.filter(menu=instance.id) .order_by("-name") .values_list("name", flat=True) ) if queryset: return queryset else: return None 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 = MenuButton.objects.filter(menu_id=obj.id).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() 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 = MenuButtonSerializer( 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", "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") parent = serializers.SerializerMethodField(read_only=True) menuPermission = serializers.SerializerMethodField(read_only=True) def get_parent(self, instance): return instance.get_parent().id if instance.get_parent() else None def get_menuPermission(self, instance): # 判断是否是超级管理员 if self.request.user.is_superuser: return MenuButton.objects.values_list("value", flat=True) else: # 根据当前角色获取权限按钮id集合 permissionIds = self.request.user.role.values_list("permission", flat=True) queryset = MenuButton.objects.filter( id__in=permissionIds, menu=instance.id ).values_list("value", flat=True) if queryset: return queryset else: return None class Meta: model = Menu fields = "__all__" 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 = [ "name", "status", "is_link", "visible", "cache", "is_catalog", ] extra_filter_backends = [] @action(methods=["GET"], detail=True, 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="获取成功")