Merge branch 'master' of https://e.coding.net/dvadmin/dvadmin3/dvadmin3
This commit is contained in:
2
backend/.gitignore
vendored
2
backend/.gitignore
vendored
@@ -91,7 +91,7 @@ ENV/
|
|||||||
**/migrations/*.py
|
**/migrations/*.py
|
||||||
!**/migrations/__init__.py
|
!**/migrations/__init__.py
|
||||||
*.pyc
|
*.pyc
|
||||||
conf/
|
conf/*
|
||||||
!conf/env.example.py
|
!conf/env.example.py
|
||||||
db.sqlite3
|
db.sqlite3
|
||||||
media/
|
media/
|
||||||
|
|||||||
@@ -55,10 +55,10 @@ INSTALLED_APPS = [
|
|||||||
"rest_framework",
|
"rest_framework",
|
||||||
"django_filters",
|
"django_filters",
|
||||||
"corsheaders", # 注册跨域app
|
"corsheaders", # 注册跨域app
|
||||||
"dvadmin.system",
|
|
||||||
"drf_yasg",
|
"drf_yasg",
|
||||||
"captcha",
|
"captcha",
|
||||||
'channels',
|
'channels',
|
||||||
|
*locals().get("CUSTOM_APPS", []), # 所有项目里写的app需要在env.py文件里的CUSTOM_APPS中
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
|||||||
10
backend/conf/env.example.py
Normal file
10
backend/conf/env.example.py
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
DATABASE_ENGINE = 'django.db.backends.mysql'
|
||||||
|
DATABASE_NAME = 'dvadmin3'
|
||||||
|
DATABASE_USER = 'root'
|
||||||
|
DATABASE_PASSWORD = 'root'
|
||||||
|
DATABASE_HOST = '127.0.0.1'
|
||||||
|
DATABASE_PORT = '3306'
|
||||||
|
ALLOWED_HOSTS = ['*']
|
||||||
|
CUSTOM_APPS = [
|
||||||
|
"dvadmin.system",
|
||||||
|
]
|
||||||
@@ -11,7 +11,6 @@
|
|||||||
"status": true,
|
"status": true,
|
||||||
"cache": false,
|
"cache": false,
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"parent": null,
|
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"name": "菜单管理",
|
"name": "菜单管理",
|
||||||
@@ -25,7 +24,6 @@
|
|||||||
"status": true,
|
"status": true,
|
||||||
"cache": false,
|
"cache": false,
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"parent": 41,
|
|
||||||
"children": [],
|
"children": [],
|
||||||
"menu_button": [
|
"menu_button": [
|
||||||
{
|
{
|
||||||
@@ -57,6 +55,30 @@
|
|||||||
"value": "menu:Delete",
|
"value": "menu:Delete",
|
||||||
"api": "/api/system/menu/{id}/",
|
"api": "/api/system/menu/{id}/",
|
||||||
"method": 3
|
"method": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "查询所有",
|
||||||
|
"value": "menu:SearchAll",
|
||||||
|
"api": "/api/system/menu/get_all_menu/",
|
||||||
|
"method": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "路由",
|
||||||
|
"value": "menu:router",
|
||||||
|
"api": "/api/system/menu/web_router/",
|
||||||
|
"method": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "上移",
|
||||||
|
"value": "menu:MoveUp",
|
||||||
|
"api": "/api/system/menu/mode_up/",
|
||||||
|
"method": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "下移",
|
||||||
|
"value": "menu:MoveDown",
|
||||||
|
"api": "/api/system/menu/mode_down/",
|
||||||
|
"method": 1
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -72,7 +94,6 @@
|
|||||||
"status": true,
|
"status": true,
|
||||||
"cache": false,
|
"cache": false,
|
||||||
"visible": false,
|
"visible": false,
|
||||||
"parent": 41,
|
|
||||||
"children": [],
|
"children": [],
|
||||||
"menu_button": [
|
"menu_button": [
|
||||||
{
|
{
|
||||||
@@ -113,7 +134,6 @@
|
|||||||
"status": true,
|
"status": true,
|
||||||
"cache": false,
|
"cache": false,
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"parent": 41,
|
|
||||||
"children": [],
|
"children": [],
|
||||||
"menu_button": [
|
"menu_button": [
|
||||||
{
|
{
|
||||||
@@ -145,6 +165,36 @@
|
|||||||
"value": "dept:Delete",
|
"value": "dept:Delete",
|
||||||
"api": "/api/system/dept/{id}/",
|
"api": "/api/system/dept/{id}/",
|
||||||
"method": 3
|
"method": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "查询所有",
|
||||||
|
"value": "dept:SearchAll",
|
||||||
|
"api": "/api/system/dept/all_dept/",
|
||||||
|
"method": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "懒加载查询所有",
|
||||||
|
"value": "dept:LazySearchAll",
|
||||||
|
"api": "/api/system/dept/dept_lazy_tree/",
|
||||||
|
"method": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "上移",
|
||||||
|
"value": "dept:MoveUp",
|
||||||
|
"api": "/api/system/dept/mode_up/",
|
||||||
|
"method": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "下移",
|
||||||
|
"value": "dept:MoveDown",
|
||||||
|
"api": "/api/system/dept/mode_down/",
|
||||||
|
"method": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "头信息",
|
||||||
|
"value": "dept:HeaderInfo",
|
||||||
|
"api": "/api/system/dept/dept_info/",
|
||||||
|
"method": 0
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -160,7 +210,6 @@
|
|||||||
"status": true,
|
"status": true,
|
||||||
"cache": false,
|
"cache": false,
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"parent": 41,
|
|
||||||
"children": [],
|
"children": [],
|
||||||
"menu_button": [
|
"menu_button": [
|
||||||
{
|
{
|
||||||
@@ -201,6 +250,64 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "列管理",
|
||||||
|
"icon": "iconfont icon-bolangneng",
|
||||||
|
"sort": 5,
|
||||||
|
"is_link": false,
|
||||||
|
"is_catalog": false,
|
||||||
|
"web_path": "/columns",
|
||||||
|
"component": "system/columns/index",
|
||||||
|
"component_name": "columns",
|
||||||
|
"status": true,
|
||||||
|
"cache": false,
|
||||||
|
"visible": true,
|
||||||
|
"children": [],
|
||||||
|
"menu_button": [
|
||||||
|
{
|
||||||
|
"name": "查询",
|
||||||
|
"value": "column:Search",
|
||||||
|
"api": "/api/system/column/",
|
||||||
|
"method": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "详情",
|
||||||
|
"value": "column:Retrieve",
|
||||||
|
"api": "/api/system/column/{id}/",
|
||||||
|
"method": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "新增",
|
||||||
|
"value": "column:Create",
|
||||||
|
"api": "/api/system/column/",
|
||||||
|
"method": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "编辑",
|
||||||
|
"value": "column:Update",
|
||||||
|
"api": "/api/system/column/{id}/",
|
||||||
|
"method": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "删除",
|
||||||
|
"value": "column:Delete",
|
||||||
|
"api": "/api/system/column/{id}/",
|
||||||
|
"method": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "所有模型表",
|
||||||
|
"value": "column:AllModel",
|
||||||
|
"api": "/api/system/column/get_models/",
|
||||||
|
"method": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "自动匹配所有字段",
|
||||||
|
"value": "column:AutoMatch",
|
||||||
|
"api": "/api/system/column/auto_match_fields/",
|
||||||
|
"method": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "用户管理",
|
"name": "用户管理",
|
||||||
"icon": "iconfont icon-icon-",
|
"icon": "iconfont icon-icon-",
|
||||||
@@ -213,7 +320,6 @@
|
|||||||
"status": true,
|
"status": true,
|
||||||
"cache": false,
|
"cache": false,
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"parent": 41,
|
|
||||||
"children": [],
|
"children": [],
|
||||||
"menu_button": [
|
"menu_button": [
|
||||||
{
|
{
|
||||||
@@ -284,7 +390,6 @@
|
|||||||
"status": true,
|
"status": true,
|
||||||
"cache": false,
|
"cache": false,
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"parent": 41,
|
|
||||||
"children": [],
|
"children": [],
|
||||||
"menu_button": [
|
"menu_button": [
|
||||||
{
|
{
|
||||||
@@ -331,7 +436,6 @@
|
|||||||
"status": true,
|
"status": true,
|
||||||
"cache": false,
|
"cache": false,
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"parent": 41,
|
|
||||||
"children": [],
|
"children": [],
|
||||||
"menu_button": [
|
"menu_button": [
|
||||||
{
|
{
|
||||||
@@ -381,7 +485,6 @@
|
|||||||
"status": true,
|
"status": true,
|
||||||
"cache": false,
|
"cache": false,
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"parent": null,
|
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"name": "系统配置",
|
"name": "系统配置",
|
||||||
@@ -395,7 +498,6 @@
|
|||||||
"status": true,
|
"status": true,
|
||||||
"cache": false,
|
"cache": false,
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"parent": 49,
|
|
||||||
"children": [],
|
"children": [],
|
||||||
"menu_button": [
|
"menu_button": [
|
||||||
{
|
{
|
||||||
@@ -442,7 +544,6 @@
|
|||||||
"status": true,
|
"status": true,
|
||||||
"cache": false,
|
"cache": false,
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"parent": 49,
|
|
||||||
"children": [],
|
"children": [],
|
||||||
"menu_button": [
|
"menu_button": [
|
||||||
{
|
{
|
||||||
@@ -489,7 +590,6 @@
|
|||||||
"status": true,
|
"status": true,
|
||||||
"cache": false,
|
"cache": false,
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"parent": 49,
|
|
||||||
"children": [],
|
"children": [],
|
||||||
"menu_button": [
|
"menu_button": [
|
||||||
{
|
{
|
||||||
@@ -536,7 +636,6 @@
|
|||||||
"status": true,
|
"status": true,
|
||||||
"cache": false,
|
"cache": false,
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"parent": 49,
|
|
||||||
"children": [],
|
"children": [],
|
||||||
"menu_button": [
|
"menu_button": [
|
||||||
{
|
{
|
||||||
@@ -580,7 +679,6 @@
|
|||||||
"status": true,
|
"status": true,
|
||||||
"cache": false,
|
"cache": false,
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"parent": null,
|
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"name": "登录日志",
|
"name": "登录日志",
|
||||||
@@ -594,7 +692,6 @@
|
|||||||
"status": true,
|
"status": true,
|
||||||
"cache": false,
|
"cache": false,
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"parent": 54,
|
|
||||||
"children": [],
|
"children": [],
|
||||||
"menu_button": [
|
"menu_button": [
|
||||||
{
|
{
|
||||||
@@ -623,7 +720,6 @@
|
|||||||
"status": true,
|
"status": true,
|
||||||
"cache": false,
|
"cache": false,
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"parent": 54,
|
|
||||||
"children": [],
|
"children": [],
|
||||||
"menu_button": [
|
"menu_button": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,12 +5,7 @@ from django.contrib.auth.models import AbstractUser, UserManager
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.core.exceptions import ObjectDoesNotExist, ValidationError
|
from django.core.exceptions import ObjectDoesNotExist, ValidationError
|
||||||
from application import dispatch
|
from application import dispatch
|
||||||
from dvadmin.utils.models import CoreModel, table_prefix
|
from dvadmin.utils.models import CoreModel, table_prefix, get_custom_app_models
|
||||||
|
|
||||||
STATUS_CHOICES = (
|
|
||||||
(0, "禁用"),
|
|
||||||
(1, "启用"),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Role(CoreModel):
|
class Role(CoreModel):
|
||||||
@@ -107,8 +102,7 @@ class Post(CoreModel):
|
|||||||
|
|
||||||
class Dept(CoreModel):
|
class Dept(CoreModel):
|
||||||
name = models.CharField(max_length=64, verbose_name="部门名称", help_text="部门名称")
|
name = models.CharField(max_length=64, verbose_name="部门名称", help_text="部门名称")
|
||||||
key = models.CharField(max_length=64, unique=True, null=True, blank=True, verbose_name="关联字符",
|
key = models.CharField(max_length=64, unique=True, null=True, blank=True, verbose_name="关联字符", help_text="关联字符")
|
||||||
help_text="关联字符")
|
|
||||||
sort = models.IntegerField(default=1, verbose_name="显示排序", help_text="显示排序")
|
sort = models.IntegerField(default=1, verbose_name="显示排序", help_text="显示排序")
|
||||||
owner = models.CharField(max_length=32, verbose_name="负责人", null=True, blank=True, help_text="负责人")
|
owner = models.CharField(max_length=32, verbose_name="负责人", null=True, blank=True, help_text="负责人")
|
||||||
phone = models.CharField(max_length=32, verbose_name="联系电话", null=True, blank=True, help_text="联系电话")
|
phone = models.CharField(max_length=32, verbose_name="联系电话", null=True, blank=True, help_text="联系电话")
|
||||||
@@ -186,6 +180,23 @@ class Menu(CoreModel):
|
|||||||
ordering = ("sort",)
|
ordering = ("sort",)
|
||||||
|
|
||||||
|
|
||||||
|
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='表名')
|
||||||
|
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='是否可查询')
|
||||||
|
is_create = models.BooleanField(default=1, verbose_name='是否可创建')
|
||||||
|
is_update = models.BooleanField(default=1, verbose_name='是否可更新')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = table_prefix + "system_columns"
|
||||||
|
verbose_name = "列权限表"
|
||||||
|
verbose_name_plural = verbose_name
|
||||||
|
ordering = ("id",)
|
||||||
|
|
||||||
|
|
||||||
class MenuButton(CoreModel):
|
class MenuButton(CoreModel):
|
||||||
menu = models.ForeignKey(
|
menu = models.ForeignKey(
|
||||||
to="Menu",
|
to="Menu",
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ from dvadmin.system.views.role_menu import RoleMenuPermissionViewSet
|
|||||||
from dvadmin.system.views.role_menu_button_permission import RoleMenuButtonPermissionViewSet
|
from dvadmin.system.views.role_menu_button_permission import RoleMenuButtonPermissionViewSet
|
||||||
from dvadmin.system.views.system_config import SystemConfigViewSet
|
from dvadmin.system.views.system_config import SystemConfigViewSet
|
||||||
from dvadmin.system.views.user import UserViewSet
|
from dvadmin.system.views.user import UserViewSet
|
||||||
|
from dvadmin.system.views.column import ColumnViewSet
|
||||||
|
|
||||||
system_url = routers.SimpleRouter()
|
system_url = routers.SimpleRouter()
|
||||||
system_url.register(r'menu', MenuViewSet)
|
system_url.register(r'menu', MenuViewSet)
|
||||||
@@ -32,6 +33,7 @@ system_url.register(r'system_config', SystemConfigViewSet)
|
|||||||
system_url.register(r'message_center', MessageCenterViewSet)
|
system_url.register(r'message_center', MessageCenterViewSet)
|
||||||
system_url.register(r'role_menu_button_permission', RoleMenuButtonPermissionViewSet)
|
system_url.register(r'role_menu_button_permission', RoleMenuButtonPermissionViewSet)
|
||||||
system_url.register(r'role_menu_permission', RoleMenuPermissionViewSet)
|
system_url.register(r'role_menu_permission', RoleMenuPermissionViewSet)
|
||||||
|
system_url.register(r'column', ColumnViewSet)
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
|||||||
107
backend/dvadmin/system/views/column.py
Normal file
107
backend/dvadmin/system/views/column.py
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from rest_framework import serializers
|
||||||
|
from rest_framework.decorators import action
|
||||||
|
from rest_framework.permissions import IsAuthenticated
|
||||||
|
|
||||||
|
from dvadmin.system.models import Columns, Role
|
||||||
|
from dvadmin.utils.models import get_custom_app_models
|
||||||
|
from dvadmin.utils.viewset import CustomModelViewSet
|
||||||
|
from dvadmin.utils.serializers import CustomModelSerializer
|
||||||
|
from dvadmin.utils.json_response import DetailResponse, ErrorResponse, SuccessResponse
|
||||||
|
|
||||||
|
|
||||||
|
class ColumnSerializer(CustomModelSerializer):
|
||||||
|
"""
|
||||||
|
列权限序列化器
|
||||||
|
"""
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Columns
|
||||||
|
fields = '__all__'
|
||||||
|
read_only_fields = ['id']
|
||||||
|
|
||||||
|
|
||||||
|
class ColumnViewSet(CustomModelViewSet):
|
||||||
|
"""
|
||||||
|
列权限视图集
|
||||||
|
"""
|
||||||
|
queryset = Columns.objects.all()
|
||||||
|
serializer_class = ColumnSerializer
|
||||||
|
|
||||||
|
def list(self, request, *args, **kwargs):
|
||||||
|
role_id = request.query_params.get('role')
|
||||||
|
app_name = request.query_params.get('app')
|
||||||
|
model_name = request.query_params.get('model')
|
||||||
|
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))
|
||||||
|
page = self.paginate_queryset(queryset)
|
||||||
|
if page is not None:
|
||||||
|
serializer = self.get_serializer(page, many=True, request=request)
|
||||||
|
return self.get_paginated_response(serializer.data)
|
||||||
|
serializer = self.get_serializer(queryset, many=True, request=request)
|
||||||
|
return SuccessResponse(data=serializer.data, msg="获取成功")
|
||||||
|
|
||||||
|
def create(self, request, *args, **kwargs):
|
||||||
|
payload = request.data
|
||||||
|
if not Role.objects.filter(pk=payload.get('role')).exists():
|
||||||
|
return ErrorResponse(msg='角色不存在')
|
||||||
|
model = None
|
||||||
|
for app in get_custom_app_models():
|
||||||
|
equal = False
|
||||||
|
for model in app:
|
||||||
|
if payload.get('model') == model['model']:
|
||||||
|
equal = True
|
||||||
|
model = model
|
||||||
|
break
|
||||||
|
if equal:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
return ErrorResponse(msg='模型表不存在')
|
||||||
|
if Columns.objects.filter(app=model['app'], model=model['model'], field_name=payload.get('field_name')).exists():
|
||||||
|
return ErrorResponse(msg='‘%s’ 字段权限已有,不可重复创建' % payload.get('title'))
|
||||||
|
serializer = self.get_serializer(data=request.data, request=request)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
self.perform_create(serializer)
|
||||||
|
return DetailResponse(data=serializer.data, msg="新增成功")
|
||||||
|
|
||||||
|
@action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated])
|
||||||
|
def get_models(self, request):
|
||||||
|
"""获取所有项目app下的model"""
|
||||||
|
res = []
|
||||||
|
for app in get_custom_app_models():
|
||||||
|
for model in app:
|
||||||
|
res.append({
|
||||||
|
'app': model['app'],
|
||||||
|
'title': model['verbose'],
|
||||||
|
'key': model['model']
|
||||||
|
})
|
||||||
|
return DetailResponse(res)
|
||||||
|
|
||||||
|
@action(methods=['POST'], detail=False, permission_classes=[IsAuthenticated])
|
||||||
|
def auto_match_fields(self, request):
|
||||||
|
"""自动匹配已有的字段"""
|
||||||
|
role_id = request.data.get('role')
|
||||||
|
app_name = request.data.get('app')
|
||||||
|
model_name = request.data.get('model')
|
||||||
|
if not role_id or not model_name or not app_name:
|
||||||
|
return DetailResponse([], msg='无操作')
|
||||||
|
for model in get_custom_app_models(app_name):
|
||||||
|
if model['model'] != model_name:
|
||||||
|
continue
|
||||||
|
for field in model['fields']:
|
||||||
|
if Columns.objects.filter(
|
||||||
|
role_id=role_id, app=app_name, model=model_name, field_name=field['name']
|
||||||
|
).exists():
|
||||||
|
continue
|
||||||
|
data = {
|
||||||
|
'role': role_id,
|
||||||
|
'app': app_name,
|
||||||
|
'model': model_name,
|
||||||
|
'field_name': field['name'],
|
||||||
|
'title': str(field['title']),
|
||||||
|
}
|
||||||
|
serializer = self.get_serializer(data=data, request=request)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
serializer.save()
|
||||||
|
return SuccessResponse(msg='匹配成功')
|
||||||
@@ -171,7 +171,6 @@ class DeptViewSet(CustomModelViewSet):
|
|||||||
previous_menu.sort, dept.sort = dept.sort, previous_menu.sort
|
previous_menu.sort, dept.sort = dept.sort, previous_menu.sort
|
||||||
previous_menu.save()
|
previous_menu.save()
|
||||||
dept.save()
|
dept.save()
|
||||||
|
|
||||||
return SuccessResponse(data=[], msg="上移成功")
|
return SuccessResponse(data=[], msg="上移成功")
|
||||||
|
|
||||||
@action(methods=['POST'], detail=False, permission_classes=[IsAuthenticated])
|
@action(methods=['POST'], detail=False, permission_classes=[IsAuthenticated])
|
||||||
@@ -187,7 +186,6 @@ class DeptViewSet(CustomModelViewSet):
|
|||||||
next_menu.sort, dept.sort = dept.sort, next_menu.sort
|
next_menu.sort, dept.sort = dept.sort, next_menu.sort
|
||||||
next_menu.save()
|
next_menu.save()
|
||||||
dept.save()
|
dept.save()
|
||||||
|
|
||||||
return SuccessResponse(data=[], msg="下移成功")
|
return SuccessResponse(data=[], msg="下移成功")
|
||||||
|
|
||||||
@action(methods=['GET'], detail=False, permission_classes=[])
|
@action(methods=['GET'], detail=False, permission_classes=[])
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from rest_framework import serializers
|
|||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
|
|
||||||
from dvadmin.system.models import Menu, RoleMenuPermission
|
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
|
||||||
from dvadmin.utils.serializers import CustomModelSerializer
|
from dvadmin.utils.serializers import CustomModelSerializer
|
||||||
from dvadmin.utils.viewset import CustomModelViewSet
|
from dvadmin.utils.viewset import CustomModelViewSet
|
||||||
@@ -23,7 +24,8 @@ class MenuSerializer(CustomModelSerializer):
|
|||||||
hasChild = serializers.SerializerMethodField()
|
hasChild = serializers.SerializerMethodField()
|
||||||
|
|
||||||
def get_menuPermission(self, instance):
|
def get_menuPermission(self, instance):
|
||||||
queryset = instance.menuPermission.order_by('-name').values_list('name', flat=True)
|
queryset = instance.menuPermission.order_by('-name').values('id', 'name', 'value')
|
||||||
|
# MenuButtonSerializer(instance.menuPermission.all(), many=True)
|
||||||
if queryset:
|
if queryset:
|
||||||
return queryset
|
return queryset
|
||||||
else:
|
else:
|
||||||
@@ -47,6 +49,11 @@ class MenuCreateSerializer(CustomModelSerializer):
|
|||||||
"""
|
"""
|
||||||
name = serializers.CharField(required=False)
|
name = serializers.CharField(required=False)
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
last_sort = Menu.objects.filter(parent_id=validated_data.get('parent', None)).order_by('-sort').first().sort
|
||||||
|
validated_data['sort'] = last_sort + 1
|
||||||
|
return super().create(validated_data)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Menu
|
model = Menu
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
@@ -148,7 +155,6 @@ class MenuViewSet(CustomModelViewSet):
|
|||||||
previous_menu.sort, menu.sort = menu.sort, previous_menu.sort
|
previous_menu.sort, menu.sort = menu.sort, previous_menu.sort
|
||||||
previous_menu.save()
|
previous_menu.save()
|
||||||
menu.save()
|
menu.save()
|
||||||
|
|
||||||
return SuccessResponse(data=[], msg="上移成功")
|
return SuccessResponse(data=[], msg="上移成功")
|
||||||
|
|
||||||
@action(methods=['POST'], detail=False, permission_classes=[])
|
@action(methods=['POST'], detail=False, permission_classes=[])
|
||||||
@@ -164,5 +170,4 @@ class MenuViewSet(CustomModelViewSet):
|
|||||||
next_menu.sort, menu.sort = menu.sort, next_menu.sort
|
next_menu.sort, menu.sort = menu.sort, next_menu.sort
|
||||||
next_menu.save()
|
next_menu.save()
|
||||||
menu.save()
|
menu.save()
|
||||||
|
|
||||||
return SuccessResponse(data=[], msg="下移成功")
|
return SuccessResponse(data=[], msg="下移成功")
|
||||||
|
|||||||
@@ -32,9 +32,6 @@ class RoleSerializer(CustomModelSerializer):
|
|||||||
read_only_fields = ["id"]
|
read_only_fields = ["id"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class RoleCreateUpdateSerializer(CustomModelSerializer):
|
class RoleCreateUpdateSerializer(CustomModelSerializer):
|
||||||
"""
|
"""
|
||||||
角色管理 创建/更新时的列化器
|
角色管理 创建/更新时的列化器
|
||||||
@@ -61,7 +58,7 @@ class RoleCreateUpdateSerializer(CustomModelSerializer):
|
|||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
class MenuPermissonSerializer(CustomModelSerializer):
|
class MenuPermissionSerializer(CustomModelSerializer):
|
||||||
"""
|
"""
|
||||||
菜单的按钮权限
|
菜单的按钮权限
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ from rest_framework.decorators import action
|
|||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import IsAuthenticated
|
||||||
|
|
||||||
from dvadmin.system.models import RoleMenuButtonPermission, Menu, MenuButton, Dept, RoleMenuPermission
|
from dvadmin.system.models import RoleMenuButtonPermission, Menu, MenuButton, Dept, RoleMenuPermission
|
||||||
|
from dvadmin.system.views.menu import MenuSerializer
|
||||||
from dvadmin.utils.json_response import DetailResponse, ErrorResponse
|
from dvadmin.utils.json_response import DetailResponse, ErrorResponse
|
||||||
from dvadmin.utils.serializers import CustomModelSerializer
|
from dvadmin.utils.serializers import CustomModelSerializer
|
||||||
from dvadmin.utils.viewset import CustomModelViewSet
|
from dvadmin.utils.viewset import CustomModelViewSet
|
||||||
@@ -37,6 +38,7 @@ class RoleMenuButtonPermissionInitSerializer(CustomModelSerializer):
|
|||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
read_only_fields = ["id"]
|
read_only_fields = ["id"]
|
||||||
|
|
||||||
|
|
||||||
class RoleMenuButtonPermissionCreateUpdateSerializer(CustomModelSerializer):
|
class RoleMenuButtonPermissionCreateUpdateSerializer(CustomModelSerializer):
|
||||||
"""
|
"""
|
||||||
初始化菜单按钮-序列化器
|
初始化菜单按钮-序列化器
|
||||||
@@ -74,16 +76,30 @@ class RoleMenuButtonPermissionViewSet(CustomModelViewSet):
|
|||||||
if is_superuser or True in is_admin:
|
if is_superuser or True in is_admin:
|
||||||
queryset = Menu.objects.filter(status=1).values('name', 'parent', 'is_catalog', menu_id=F('id'))
|
queryset = Menu.objects.filter(status=1).values('name', 'parent', 'is_catalog', menu_id=F('id'))
|
||||||
for item in queryset:
|
for item in queryset:
|
||||||
btn_name = MenuButton.objects.filter(menu=item['menu_id']).values_list(
|
btn_name = MenuButton.objects.filter(menu=item['menu_id']).values_list('name', flat=True)
|
||||||
'name', flat=True)
|
data.append({
|
||||||
data.append({'menu_id': item['menu_id'], 'name': item['name'], 'parent': item['parent'],
|
'menu_id': item['menu_id'],
|
||||||
'permission': ','.join(btn_name), 'is_catalog': item['is_catalog']})
|
'name': item['name'],
|
||||||
|
'parent': item['parent'],
|
||||||
|
'permission': btn_name,
|
||||||
|
'is_catalog': item['is_catalog']
|
||||||
|
})
|
||||||
else:
|
else:
|
||||||
role_id = request.user.role.values_list('id', flat=True)
|
role_id = request.user.role.values_list('id', flat=True)
|
||||||
queryset = RoleMenuPermission.objects.filter(role__in=role_id).values('menu_id',name=F('menu__name'),parent=F('menu__parent'),is_catalog=F('menu__is_catalog')).distinct()
|
queryset = RoleMenuPermission.objects.filter(role__in=role_id).values(
|
||||||
|
'menu_id', name=F('menu__name'), parent=F('menu__parent'), is_catalog=F('menu__is_catalog')
|
||||||
|
).distinct()
|
||||||
for item in queryset:
|
for item in queryset:
|
||||||
btn_name = RoleMenuButtonPermission.objects.filter(menu_button__menu=item['menu_id']).values_list('menu_button__name',flat=True)
|
btn_name = RoleMenuButtonPermission.objects.filter(
|
||||||
data.append({'menu_id':item['menu_id'], 'name':item['name'], 'parent':item['parent'],'permission':','.join(btn_name),'is_catalog':item['is_catalog']})
|
menu_button__menu=item['menu_id']
|
||||||
|
).values_list('menu_button__name', flat=True)
|
||||||
|
data.append({
|
||||||
|
'menu_id': item['menu_id'],
|
||||||
|
'name': item['name'],
|
||||||
|
'parent': item['parent'],
|
||||||
|
'permission': btn_name,
|
||||||
|
'is_catalog': item['is_catalog']
|
||||||
|
})
|
||||||
return DetailResponse(data=data)
|
return DetailResponse(data=data)
|
||||||
|
|
||||||
@action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated])
|
@action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated])
|
||||||
@@ -101,10 +117,9 @@ class RoleMenuButtonPermissionViewSet(CustomModelViewSet):
|
|||||||
queryset = MenuButton.objects.filter(menu=menu_id).values('id', 'name')
|
queryset = MenuButton.objects.filter(menu=menu_id).values('id', 'name')
|
||||||
else:
|
else:
|
||||||
role_list = request.user.role.values_list('id', flat=True)
|
role_list = request.user.role.values_list('id', flat=True)
|
||||||
queryset = RoleMenuButtonPermission.objects.filter(role__in=role_list,menu_button__menu=menu_id).values(
|
queryset = RoleMenuButtonPermission.objects.filter(
|
||||||
btn_id=F('menu_button__id'),
|
role__in=role_list, menu_button__menu=menu_id
|
||||||
name=F('menu_button__name')
|
).values(btn_id=F('menu_button__id'), name=F('menu_button__name'))
|
||||||
)
|
|
||||||
return DetailResponse(data=queryset)
|
return DetailResponse(data=queryset)
|
||||||
return ErrorResponse(msg="参数错误")
|
return ErrorResponse(msg="参数错误")
|
||||||
|
|
||||||
@@ -145,7 +160,9 @@ class RoleMenuButtonPermissionViewSet(CustomModelViewSet):
|
|||||||
role_list = request.user.role.values_list('id', flat=True)
|
role_list = request.user.role.values_list('id', flat=True)
|
||||||
if params := request.query_params:
|
if params := request.query_params:
|
||||||
if menu_button_id := params.get('menu_button', None):
|
if menu_button_id := params.get('menu_button', None):
|
||||||
role_queryset = RoleMenuButtonPermission.objects.filter(role__in=role_list,menu_button__id=menu_button_id).values_list('data_range',flat=True)
|
role_queryset = RoleMenuButtonPermission.objects.filter(
|
||||||
|
role__in=role_list, menu_button__id=menu_button_id
|
||||||
|
).values_list('data_range', flat=True)
|
||||||
data_range_list = list(set(role_queryset))
|
data_range_list = list(set(role_queryset))
|
||||||
for item in data_range_list:
|
for item in data_range_list:
|
||||||
if item == 0:
|
if item == 0:
|
||||||
@@ -223,8 +240,6 @@ class RoleMenuButtonPermissionViewSet(CustomModelViewSet):
|
|||||||
)
|
)
|
||||||
return DetailResponse(data=queryset)
|
return DetailResponse(data=queryset)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@action(methods=['get'], detail=False, permission_classes=[IsAuthenticated])
|
@action(methods=['get'], detail=False, permission_classes=[IsAuthenticated])
|
||||||
def menu_to_button(self, request):
|
def menu_to_button(self, request):
|
||||||
"""
|
"""
|
||||||
@@ -277,4 +292,3 @@ class RoleMenuButtonPermissionViewSet(CustomModelViewSet):
|
|||||||
queryset = RoleMenuPermission.objects.filter(role_id=role_id).values_list('menu_id', flat=True).distinct()
|
queryset = RoleMenuPermission.objects.filter(role_id=role_id).values_list('menu_id', flat=True).distinct()
|
||||||
|
|
||||||
return DetailResponse(data=queryset)
|
return DetailResponse(data=queryset)
|
||||||
|
|
||||||
|
|||||||
@@ -6,15 +6,17 @@
|
|||||||
@Created on: 2021/5/31 031 22:08
|
@Created on: 2021/5/31 031 22:08
|
||||||
@Remark: 公共基础model类
|
@Remark: 公共基础model类
|
||||||
"""
|
"""
|
||||||
|
from importlib import import_module
|
||||||
|
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import QuerySet
|
from django.conf import settings
|
||||||
|
|
||||||
from application import settings
|
from application import settings
|
||||||
table_prefix = settings.TABLE_PREFIX # 数据库表名前缀
|
table_prefix = settings.TABLE_PREFIX # 数据库表名前缀
|
||||||
|
|
||||||
|
|
||||||
class SoftDeleteQuerySet(QuerySet):
|
class SoftDeleteQuerySet(models.QuerySet):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@@ -106,3 +108,38 @@ def get_all_models_objects(model_name=None):
|
|||||||
if model_name:
|
if model_name:
|
||||||
return settings.ALL_MODELS_OBJECTS[model_name] or {}
|
return settings.ALL_MODELS_OBJECTS[model_name] or {}
|
||||||
return settings.ALL_MODELS_OBJECTS or {}
|
return settings.ALL_MODELS_OBJECTS or {}
|
||||||
|
|
||||||
|
|
||||||
|
def get_model_from_app(app_name):
|
||||||
|
"""获取模型里的字段"""
|
||||||
|
model_module = import_module(app_name + '.models')
|
||||||
|
filter_model = [
|
||||||
|
getattr(model_module, item) for item in dir(model_module)
|
||||||
|
if item != 'CoreModel' and issubclass(getattr(model_module, item).__class__, models.base.ModelBase)
|
||||||
|
]
|
||||||
|
model_list = []
|
||||||
|
for model in filter_model:
|
||||||
|
if model.__name__ == 'AbstractUser':
|
||||||
|
continue
|
||||||
|
fields = [
|
||||||
|
{'title': field.verbose_name, 'name': field.name, 'object': field}
|
||||||
|
for field in model._meta.fields
|
||||||
|
]
|
||||||
|
model_list.append({
|
||||||
|
'app': app_name,
|
||||||
|
'verbose': model._meta.verbose_name,
|
||||||
|
'model': model.__name__,
|
||||||
|
'object': model,
|
||||||
|
'fields': fields
|
||||||
|
})
|
||||||
|
return model_list
|
||||||
|
|
||||||
|
|
||||||
|
def get_custom_app_models(app_name=None):
|
||||||
|
"""获取所有项目写的app里的models"""
|
||||||
|
if app_name:
|
||||||
|
return get_model_from_app(app_name)
|
||||||
|
res = []
|
||||||
|
for app in settings.CUSTOM_APPS:
|
||||||
|
res.append(get_model_from_app(app))
|
||||||
|
return res
|
||||||
|
|||||||
@@ -40,13 +40,11 @@ class CustomPagination(PageNumberPagination):
|
|||||||
try:
|
try:
|
||||||
self.page = paginator.page(page_number)
|
self.page = paginator.page(page_number)
|
||||||
except InvalidPage as exc:
|
except InvalidPage as exc:
|
||||||
|
|
||||||
# msg = self.invalid_page_message.format(
|
# msg = self.invalid_page_message.format(
|
||||||
# page_number=page_number, message=str(exc)
|
# page_number=page_number, message=str(exc)
|
||||||
# )
|
# )
|
||||||
# raise NotFound(msg)
|
# raise NotFound(msg)
|
||||||
empty = False
|
empty = False
|
||||||
pass
|
|
||||||
|
|
||||||
if paginator.num_pages > 1 and self.template is not None:
|
if paginator.num_pages > 1 and self.template is not None:
|
||||||
# The browsable API should display pagination controls.
|
# The browsable API should display pagination controls.
|
||||||
@@ -58,15 +56,15 @@ class CustomPagination(PageNumberPagination):
|
|||||||
self.page = []
|
self.page = []
|
||||||
|
|
||||||
return list(self.page)
|
return list(self.page)
|
||||||
|
|
||||||
def get_paginated_response(self, data):
|
def get_paginated_response(self, data):
|
||||||
code = 2000
|
code = 2000
|
||||||
msg = 'success'
|
msg = 'success'
|
||||||
page = int(self.get_page_number(self.request, paginator)) or 1
|
page = int(self.get_page_number(self.request, paginator)) or 1
|
||||||
total = self.page.paginator.count if self.page else 0
|
total = self.page.paginator.count if self.page else 0
|
||||||
limit = int(self.get_page_size(self.request)) or 10
|
limit = int(self.get_page_size(self.request)) or 10
|
||||||
is_next= self.page.has_next()
|
is_next = self.page.has_next() if self.page else False
|
||||||
is_previous= self.page.has_previous()
|
is_previous = self.page.has_previous() if self.page else False
|
||||||
data=data
|
|
||||||
|
|
||||||
if not data:
|
if not data:
|
||||||
code = 2000
|
code = 2000
|
||||||
|
|||||||
Reference in New Issue
Block a user