217 lines
6.6 KiB
Python
217 lines
6.6 KiB
Python
# -*- 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="获取成功")
|