1.完成新版菜单管理

This commit is contained in:
猿小天
2023-10-27 16:59:25 +08:00
parent 7159253c6b
commit bd8fef9a04
15 changed files with 570 additions and 206 deletions

View File

@@ -112,7 +112,7 @@ class MenuInitSerializer(CustomModelSerializer):
class Meta:
model = Menu
fields = ['name', 'icon', 'sort', 'is_link', 'is_catalog', 'web_path', 'component', 'component_name', 'status',
fields = ['name', 'icon', 'sort', 'is_link', 'menu_type', 'web_path', 'component', 'component_name', 'status',
'cache', 'visible', 'parent', 'children', 'menu_button', 'creator', 'dept_belong_id']
extra_kwargs = {
'creator': {'write_only': True},

View File

@@ -4,7 +4,7 @@
"icon": "iconfont icon-xitongshezhi",
"sort": 1,
"is_link": false,
"is_catalog": true,
"menu_type": 0,
"web_path": "/system",
"component": "",
"component_name": "",
@@ -17,7 +17,7 @@
"icon": "iconfont icon-caidan",
"sort": 1,
"is_link": false,
"is_catalog": false,
"menu_type": 1,
"web_path": "/menu",
"component": "system/menu/index",
"component_name": "menu",
@@ -87,7 +87,7 @@
"icon": "dot-circle-o",
"sort": 2,
"is_link": false,
"is_catalog": false,
"menu_type": 1,
"web_path": "/menuButton",
"component": "system/menuButton/index",
"component_name": "menuButton",
@@ -127,7 +127,7 @@
"icon": "ele-OfficeBuilding",
"sort": 3,
"is_link": false,
"is_catalog": false,
"menu_type": 1,
"web_path": "/dept",
"component": "system/dept/index",
"component_name": "dept",
@@ -203,7 +203,7 @@
"icon": "ele-ColdDrink",
"sort": 4,
"is_link": false,
"is_catalog": false,
"menu_type": 1,
"web_path": "/role",
"component": "system/role/index",
"component_name": "role",
@@ -255,7 +255,7 @@
"icon": "iconfont icon-bolangneng",
"sort": 5,
"is_link": false,
"is_catalog": false,
"menu_type": 1,
"web_path": "/columns",
"component": "system/columns/index",
"component_name": "columns",
@@ -313,7 +313,7 @@
"icon": "iconfont icon-icon-",
"sort": 6,
"is_link": false,
"is_catalog": false,
"menu_type": 1,
"web_path": "/user",
"component": "system/user/index",
"component_name": "user",
@@ -383,7 +383,7 @@
"icon": "iconfont icon-xiaoxizhongxin",
"sort": 7,
"is_link": false,
"is_catalog": false,
"menu_type": 1,
"web_path": "/messageCenter",
"component": "system/messageCenter/index",
"component_name": "messageCenter",
@@ -429,7 +429,7 @@
"icon": "ele-SetUp",
"sort": 8,
"is_link": false,
"is_catalog": false,
"menu_type": 1,
"web_path": "/apiWhiteList",
"component": "system/whiteList/index",
"component_name": "whiteList",
@@ -478,7 +478,7 @@
"icon": "iconfont icon-configure",
"sort": 2,
"is_link": false,
"is_catalog": true,
"menu_type": 0,
"web_path": "/generalConfig",
"component": "",
"component_name": "",
@@ -491,7 +491,7 @@
"icon": "iconfont icon-system",
"sort": 0,
"is_link": false,
"is_catalog": false,
"menu_type": 1,
"web_path": "/config",
"component": "system/config/index",
"component_name": "config",
@@ -537,7 +537,7 @@
"icon": "iconfont icon-dict",
"sort": 1,
"is_link": false,
"is_catalog": false,
"menu_type": 1,
"web_path": "/dictionary",
"component": "system/dictionary/index",
"component_name": "dictionary",
@@ -583,7 +583,7 @@
"icon": "iconfont icon-Area",
"sort": 2,
"is_link": false,
"is_catalog": false,
"menu_type": 1,
"web_path": "/areas",
"component": "system/areas/index",
"component_name": "areas",
@@ -629,7 +629,7 @@
"icon": "iconfont icon-file",
"sort": 3,
"is_link": false,
"is_catalog": false,
"menu_type": 1,
"web_path": "/file",
"component": "system/fileList/index",
"component_name": "file",
@@ -672,7 +672,7 @@
"icon": "iconfont icon-rizhi",
"sort": 3,
"is_link": false,
"is_catalog": true,
"menu_type": 0,
"web_path": "/log",
"component": "",
"component_name": "",
@@ -685,7 +685,7 @@
"icon": "iconfont icon-guanlidenglurizhi",
"sort": 1,
"is_link": false,
"is_catalog": false,
"menu_type": 1,
"web_path": "/loginLog",
"component": "system/log/loginLog/index",
"component_name": "loginLog",
@@ -713,7 +713,7 @@
"icon": "iconfont icon-caozuorizhi",
"sort": 2,
"is_link": false,
"is_catalog": false,
"menu_type": 1,
"web_path": "/operationLog",
"component": "system/log/operationLog/index",
"component_name": "operationLog",

View File

@@ -156,22 +156,24 @@ class Menu(CoreModel):
help_text="上级菜单",
)
icon = models.CharField(max_length=64, verbose_name="菜单图标", null=True, blank=True, help_text="菜单图标")
name = models.CharField(max_length=64, verbose_name="菜单名称", help_text="菜单名称")
name = models.CharField(max_length=64, verbose_name="目录名称/菜单名称/按钮名称", help_text="目录名称/菜单名称/按钮名称")
sort = models.IntegerField(default=1, verbose_name="显示排序", null=True, blank=True, help_text="显示排序")
ISLINK_CHOICES = (
(0, ""),
(1, ""),
)
is_link = models.BooleanField(default=False, verbose_name="是否外链", help_text="是否外链")
is_catalog = models.BooleanField(default=False, verbose_name="是否目录", help_text="是否目录")
MENU_TYPE_CHOICES =(
(0, "目录"),
(1, "菜单"),
(2, "按钮"),
)
menu_type = models.IntegerField(default=0, verbose_name="菜单类型", help_text="菜单类型")
web_path = models.CharField(max_length=128, verbose_name="路由地址", null=True, blank=True, help_text="路由地址")
component = models.CharField(max_length=128, verbose_name="组件地址", null=True, blank=True, help_text="组件地址")
component = models.CharField(max_length=200, verbose_name="组件地址/按钮权限值", null=True, blank=True, help_text="组件地址/按钮权限值")
component_name = models.CharField(max_length=50, verbose_name="组件名称", null=True, blank=True,
help_text="组件名称")
status = models.BooleanField(default=True, blank=True, verbose_name="菜单状态", help_text="菜单状态")
cache = models.BooleanField(default=False, blank=True, verbose_name="是否页面缓存", help_text="是否页面缓存")
visible = models.BooleanField(default=True, blank=True, verbose_name="侧边栏中是否显示",
help_text="侧边栏中是否显示")
frame_out = models.BooleanField(default=False, blank=True, verbose_name="是否主框架外", help_text="是否主框架外")
class Meta:
db_table = table_prefix + "system_menu"
@@ -184,7 +186,6 @@ class Columns(CoreModel):
role = models.ForeignKey(to='Role', on_delete=models.CASCADE, verbose_name='角色', db_constraint=False)
app = models.CharField(max_length=64, verbose_name='应用名')
model = models.CharField(max_length=64, verbose_name='表名')
menu = models.ForeignKey(to='Menu', on_delete=models.CASCADE, verbose_name='菜单', db_constraint=False)
field_name = models.CharField(max_length=64, verbose_name='模型表字段名')
title = models.CharField(max_length=64, verbose_name='字段显示名')
is_query = models.BooleanField(default=1, verbose_name='是否可查询')
@@ -457,7 +458,7 @@ class SystemConfig(CoreModel):
help_text="父级",
)
title = models.CharField(max_length=50, verbose_name="标题", help_text="标题")
key = models.CharField(max_length=20, verbose_name="", help_text="", db_index=True)
key = models.CharField(max_length=50, verbose_name="", help_text="", db_index=True)
value = models.JSONField(max_length=100, verbose_name="", help_text="", null=True, blank=True)
sort = models.IntegerField(default=0, verbose_name="排序", help_text="排序", blank=True)
status = models.BooleanField(default=True, verbose_name="启用状态", help_text="启用状态")

View File

@@ -32,10 +32,9 @@ class ColumnViewSet(CustomModelViewSet):
role_id = request.query_params.get('role')
app_name = request.query_params.get('app')
model_name = request.query_params.get('model')
menu = request.query_params.get('menu')
if not role_id or not model_name or not app_name or not menu:
if not role_id or not model_name or not app_name:
return SuccessResponse([])
queryset = self.filter_queryset(self.get_queryset().filter(role_id=role_id, model=model_name, app=app_name,menu_id=menu))
queryset = self.filter_queryset(self.get_queryset().filter(role_id=role_id, model=model_name, app=app_name))
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True, request=request)

View File

@@ -11,7 +11,7 @@ from rest_framework.decorators import action
from dvadmin.system.models import Menu, RoleMenuPermission
from dvadmin.system.views.menu_button import MenuButtonSerializer
from dvadmin.utils.json_response import SuccessResponse, ErrorResponse
from dvadmin.utils.json_response import SuccessResponse, ErrorResponse, DetailResponse
from dvadmin.utils.serializers import CustomModelSerializer
from dvadmin.utils.viewset import CustomModelViewSet
@@ -21,7 +21,7 @@ class MenuSerializer(CustomModelSerializer):
菜单表的简单序列化器
"""
menuPermission = serializers.SerializerMethodField(read_only=True)
hasChild = serializers.SerializerMethodField()
hasChildren = serializers.SerializerMethodField()
def get_menuPermission(self, instance):
queryset = instance.menuPermission.order_by('-name').values('id', 'name', 'value')
@@ -31,7 +31,7 @@ class MenuSerializer(CustomModelSerializer):
else:
return None
def get_hasChild(self, instance):
def get_hasChildren(self, instance):
hasChild = Menu.objects.filter(parent=instance.id)
if hasChild:
return True
@@ -71,7 +71,7 @@ class WebRouterSerializer(CustomModelSerializer):
class Meta:
model = Menu
fields = (
'id', 'parent', 'icon', 'sort', 'path', 'name', 'title', 'is_link', 'is_catalog', 'web_path', 'component',
'id', 'parent', 'icon', 'sort', 'path', 'name', 'title', 'is_link', 'menu_type', 'web_path', 'component',
'component_name', 'cache', 'visible', 'status')
read_only_fields = ["id"]
@@ -90,37 +90,31 @@ class MenuViewSet(CustomModelViewSet):
create_serializer_class = MenuCreateSerializer
update_serializer_class = MenuCreateSerializer
search_fields = ['name', 'status']
filter_fields = ['parent', 'name', 'status', 'is_link', 'visible', 'cache', 'is_catalog']
filter_fields = ['parent', 'name', 'status', 'is_link', 'visible', 'cache', 'menu_type']
def list(self, request):
@action(methods=['get'], detail=False)
def tree(self, request):
"""懒加载"""
request.query_params._mutable = True
params = request.query_params
parent = params.get('parent', None)
page = params.get('page', None)
limit = params.get('limit', None)
if page:
del params['page']
if limit:
del params['limit']
if params:
if parent:
queryset = self.queryset.filter(parent=parent)
else:
queryset = self.queryset.filter()
else:
queryset = self.queryset.filter(parent__isnull=True)
queryset = self.filter_queryset(queryset)
menu_type = params.get('menu_type', 0)
queryset = Menu.objects.filter(menu_type=menu_type).order_by('sort')
serializer = MenuSerializer(queryset, many=True, request=request)
data = serializer.data
return SuccessResponse(data=data)
return DetailResponse(data=data)
@action(methods=['get'], detail=True)
def getChildren(self,request,pk):
queryset = Menu.objects.filter(parent=pk)
serializer = MenuSerializer(queryset, many=True, request=request)
data = serializer.data
return DetailResponse(data=data)
@action(methods=['GET'], detail=False, permission_classes=[])
def web_router(self, request):
"""用于前端获取当前角色的路由"""
user = request.user
is_admin = user.role.values_list('admin', flat=True)
if user.is_superuser or True in is_admin:
if user.is_superuser:
queryset = self.queryset.filter(status=1)
else:
role_list = user.role.values_list('id', flat=True)

View File

@@ -100,7 +100,7 @@ class RoleMenuPermissionSerializer(CustomModelSerializer):
def get_columns(self, instance):
params = self.request.query_params
col_list = Columns.objects.filter(role__id=params.get('role'),menu__id=instance['id'])
col_list = Columns.objects.filter(role__id=params.get('role'))
serializer = RoleColumnsSerializer(col_list,many=True,request=self.request)
return serializer.data

View File

@@ -79,6 +79,5 @@ class CustomPagination(PageNumberPagination):
('total', total),
('is_next', is_next),
('is_previous', is_previous),
('data', data),
('permission', self.request.permission_fields)
('data', data)
]))