menu.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. # -*- coding: utf-8 -*-
  2. """
  3. @author: Allen
  4. @Created on: 2023/10/18
  5. @Remark: 菜单模块
  6. """
  7. from rest_framework import serializers
  8. from rest_framework.decorators import action
  9. from dvadmin.system.models import Menu, MenuButton
  10. from dvadmin.system.views.menu_button import MenuButtonInitSerializer
  11. from dvadmin.utils.json_response import SuccessResponse
  12. from dvadmin.utils.serializers import CustomModelSerializer
  13. from dvadmin.utils.viewset import CustomModelViewSet
  14. class MenuSerializer(CustomModelSerializer):
  15. """
  16. 菜单表的简单序列化器
  17. """
  18. menuPermission = serializers.SerializerMethodField(read_only=True)
  19. hasChild = serializers.SerializerMethodField()
  20. def get_menuPermission(self, instance):
  21. queryset = instance.menuPermission.order_by('-name').values_list('name', flat=True)
  22. if queryset:
  23. return queryset
  24. else:
  25. return None
  26. def get_hasChild(self, instance):
  27. hasChild = Menu.objects.filter(parent=instance.id)
  28. if hasChild:
  29. return True
  30. return False
  31. class Meta:
  32. model = Menu
  33. fields = "__all__"
  34. read_only_fields = ["id"]
  35. class MenuCreateSerializer(CustomModelSerializer):
  36. """
  37. 菜单表的创建序列化器
  38. """
  39. name = serializers.CharField(required=False)
  40. class Meta:
  41. model = Menu
  42. fields = "__all__"
  43. read_only_fields = ["id"]
  44. class MenuInitSerializer(CustomModelSerializer):
  45. """
  46. 递归深度获取数信息(用于生成初始化json文件)
  47. """
  48. name = serializers.CharField(required=False)
  49. children = serializers.SerializerMethodField()
  50. menu_button = serializers.SerializerMethodField()
  51. def get_children(self, obj: Menu):
  52. data = []
  53. instance = Menu.objects.filter(parent_id=obj.id)
  54. if instance:
  55. serializer = MenuInitSerializer(instance=instance, many=True)
  56. data = serializer.data
  57. return data
  58. def get_menu_button(self, obj: Menu):
  59. data = []
  60. instance = obj.menuPermission.order_by('method')
  61. if instance:
  62. data = list(instance.values('name', 'value', 'api', 'method'))
  63. return data
  64. def save(self, **kwargs):
  65. instance = super().save(**kwargs)
  66. children = self.initial_data.get('children')
  67. menu_button = self.initial_data.get('menu_button')
  68. # 菜单表
  69. if children:
  70. for menu_data in children:
  71. menu_data['parent'] = instance.id
  72. filter_data = {
  73. "name": menu_data['name'],
  74. "web_path": menu_data['web_path'],
  75. "component": menu_data['component'],
  76. "component_name": menu_data['component_name'],
  77. }
  78. instance_obj = Menu.objects.filter(**filter_data).first()
  79. if instance_obj and not self.initial_data.get('reset'):
  80. continue
  81. serializer = MenuInitSerializer(instance_obj, data=menu_data, request=self.request)
  82. serializer.is_valid(raise_exception=True)
  83. serializer.save()
  84. # 菜单按钮
  85. if menu_button:
  86. for menu_button_data in menu_button:
  87. menu_button_data['menu'] = instance.id
  88. filter_data = {
  89. "menu": menu_button_data['menu'],
  90. "value": menu_button_data['value']
  91. }
  92. instance_obj = MenuButton.objects.filter(**filter_data).first()
  93. serializer = MenuButtonInitSerializer(instance_obj, data=menu_button_data, request=self.request)
  94. serializer.is_valid(raise_exception=True)
  95. serializer.save()
  96. return instance
  97. class Meta:
  98. model = Menu
  99. fields = ['name', 'icon', 'sort', 'is_link', 'is_catalog', 'web_path', 'component', 'component_name', 'status',
  100. 'cache', 'visible', 'parent', 'children', 'menu_button', 'frame_out', 'creator', 'dept_belong_id']
  101. extra_kwargs = {
  102. 'creator': {'write_only': True},
  103. 'dept_belong_id': {'write_only': True}
  104. }
  105. read_only_fields = ['id', 'children']
  106. class WebRouterSerializer(CustomModelSerializer):
  107. """
  108. 前端菜单路由的简单序列化器
  109. """
  110. path = serializers.CharField(source="web_path")
  111. title = serializers.CharField(source="name")
  112. menuPermission = serializers.SerializerMethodField(read_only=True)
  113. def get_menuPermission(self, instance):
  114. # 判断是否是超级管理员
  115. if self.request.user.is_superuser:
  116. return instance.menuPermission.values_list('value', flat=True)
  117. else:
  118. # 根据当前角色获取权限按钮id集合
  119. permissionIds = self.request.user.role.values_list('permission', flat=True)
  120. queryset = instance.menuPermission.filter(id__in=permissionIds, menu=instance.id).values_list('value',
  121. flat=True)
  122. if queryset:
  123. return queryset
  124. else:
  125. return None
  126. class Meta:
  127. model = Menu
  128. fields = (
  129. 'id', 'parent', 'icon', 'sort', 'path', 'name', 'title', 'is_link', 'is_catalog', 'web_path', 'component',
  130. 'component_name', 'cache', 'visible', 'menuPermission', 'frame_out')
  131. read_only_fields = ["id"]
  132. class MenuViewSet(CustomModelViewSet):
  133. """
  134. 菜单管理接口
  135. list:查询
  136. create:新增
  137. update:修改
  138. retrieve:单例
  139. destroy:删除
  140. """
  141. queryset = Menu.objects.all()
  142. serializer_class = MenuSerializer
  143. create_serializer_class = MenuCreateSerializer
  144. update_serializer_class = MenuCreateSerializer
  145. search_fields = ['name', 'status']
  146. filter_fields = ['parent', 'name', 'status', 'is_link', 'visible', 'cache', 'is_catalog']
  147. # extra_filter_backends = []
  148. @action(methods=['GET'], detail=False, permission_classes=[])
  149. def web_router(self, request):
  150. """用于前端获取当前角色的路由"""
  151. user = request.user
  152. queryset = self.queryset.filter(status=1)
  153. if not user.is_superuser:
  154. menuIds = user.role.values_list('menu__id', flat=True)
  155. queryset = Menu.objects.filter(id__in=menuIds, status=1)
  156. serializer = WebRouterSerializer(queryset, many=True, request=request)
  157. data = serializer.data
  158. return SuccessResponse(data=data, total=len(data), msg="获取成功")
  159. def list(self, request):
  160. """懒加载"""
  161. params = request.query_params
  162. parent = params.get('parent', None)
  163. if params:
  164. if parent:
  165. queryset = self.queryset.filter(parent=parent)
  166. else:
  167. queryset = self.queryset
  168. else:
  169. queryset = self.queryset.filter(parent__isnull=True)
  170. queryset = self.filter_queryset(queryset)
  171. serializer = MenuSerializer(queryset, many=True, request=request)
  172. data = serializer.data
  173. return SuccessResponse(data=data)