fix(菜单管理): 菜单管理
优化
This commit is contained in:
155
backend/dvadmin/utils/crud_mixin.py
Normal file
155
backend/dvadmin/utils/crud_mixin.py
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from rest_framework.decorators import action
|
||||||
|
from rest_framework.permissions import AllowAny
|
||||||
|
|
||||||
|
from dvadmin.utils.json_response import DetailResponse
|
||||||
|
|
||||||
|
|
||||||
|
class FastCrudMixin:
|
||||||
|
"""
|
||||||
|
定义快速CRUD数据操作的通用方法
|
||||||
|
"""
|
||||||
|
# 需要CRUD的字段
|
||||||
|
crud_fields = None
|
||||||
|
# 排除CRUD的字段
|
||||||
|
exclude_fields = None
|
||||||
|
# 自定义CRUD的JSON
|
||||||
|
custom_crud_json = None
|
||||||
|
# 需要修改的CRUD键值对
|
||||||
|
crud_update_key_value = None
|
||||||
|
|
||||||
|
# 将Django的字段类型处理为JS类型
|
||||||
|
def __handle_type(self, type):
|
||||||
|
if type in ['BigAutoField', 'CharField']:
|
||||||
|
return "input"
|
||||||
|
if type == 'DateTimeField':
|
||||||
|
return "datetime"
|
||||||
|
if type == 'DateField':
|
||||||
|
return "date"
|
||||||
|
if type == 'IntegerField':
|
||||||
|
return "number"
|
||||||
|
if type == 'BooleanField':
|
||||||
|
return "dict-switch"
|
||||||
|
|
||||||
|
# 获取字段属性信息
|
||||||
|
def __get_field_attribute(self):
|
||||||
|
result = []
|
||||||
|
queryset = self.get_queryset()
|
||||||
|
__name = ""
|
||||||
|
__verbose_name = ""
|
||||||
|
__type = "text"
|
||||||
|
# 判断指定CRUD字段
|
||||||
|
if self.crud_fields and type(self.crud_fields == list):
|
||||||
|
for item in self.crud_fields:
|
||||||
|
try:
|
||||||
|
field = queryset.model._meta.get_field(item)
|
||||||
|
field_type = field.get_internal_type()
|
||||||
|
__name = field.name
|
||||||
|
# 判断类型是否为外键类型,外键类型需要特殊方式获取verbose_name
|
||||||
|
if field_type in ['ForeignKey', 'OneToOneField', 'ManyToManyField']:
|
||||||
|
continue
|
||||||
|
# try:
|
||||||
|
# verbose_name = Users._meta.get_field(str(field.name)).verbose_name
|
||||||
|
# except:
|
||||||
|
# pass
|
||||||
|
else:
|
||||||
|
__verbose_name = field.verbose_name
|
||||||
|
__type = self.__handle_type(field_type)
|
||||||
|
except:
|
||||||
|
continue
|
||||||
|
result.append({"key": __name, "title": __verbose_name, "type": __type})
|
||||||
|
else:
|
||||||
|
# 获取model的所有字段及属性
|
||||||
|
model_fields = queryset.model._meta.get_fields()
|
||||||
|
# 遍历所有字段属性
|
||||||
|
for field in model_fields:
|
||||||
|
field_type = field.get_internal_type()
|
||||||
|
__name = field.name
|
||||||
|
# 判断需要排除的CRUD字段
|
||||||
|
if self.exclude_fields and type(self.exclude_fields == list):
|
||||||
|
if __name in self.exclude_fields:
|
||||||
|
continue
|
||||||
|
# 判断类型是否为外键类型,外键类型需要特殊方式获取verbose_name
|
||||||
|
if field_type in ['ForeignKey', 'OneToOneField', 'ManyToManyField']:
|
||||||
|
continue
|
||||||
|
# try:
|
||||||
|
# verbose_name = Users._meta.get_field(str(field.name)).verbose_name
|
||||||
|
# except:
|
||||||
|
# pass
|
||||||
|
else:
|
||||||
|
__verbose_name = field.verbose_name
|
||||||
|
__type = self.__handle_type(field_type)
|
||||||
|
result.append({"key": __name, "title": __verbose_name, "type": __type})
|
||||||
|
return result
|
||||||
|
|
||||||
|
#获取key
|
||||||
|
def __find_key(self,dct: dict,
|
||||||
|
target_key: str,
|
||||||
|
level: int = -1,
|
||||||
|
index: int = -1) -> tuple:
|
||||||
|
"""Find a key within a nested dictionary and return its level and index."""
|
||||||
|
for k, v in dct.items():
|
||||||
|
level += 1
|
||||||
|
index += 1
|
||||||
|
if k == target_key:
|
||||||
|
return level, index
|
||||||
|
elif isinstance(v, list):
|
||||||
|
for i, dct_ in enumerate(v):
|
||||||
|
if isinstance(dct_, dict):
|
||||||
|
result = self.__find_key(dct_, target_key)
|
||||||
|
if result is not None:
|
||||||
|
return result
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
elif isinstance(v, str) or isinstance(v, int) or isinstance(v, float):
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 修改字典中key的value
|
||||||
|
def __update_nested_dict(self,nested_dict: dict,
|
||||||
|
target_key: str,
|
||||||
|
new_value) -> dict:
|
||||||
|
"""Update a nested dictionary with a new value."""
|
||||||
|
split_target_key = target_key.split('.')
|
||||||
|
if len(split_target_key) > 1:
|
||||||
|
new_dict = nested_dict[split_target_key[0]]
|
||||||
|
for item in split_target_key[1:-1]:
|
||||||
|
new_dict = new_dict[item]
|
||||||
|
self.__update_nested_dict(new_dict, split_target_key[-1], new_value)
|
||||||
|
else:
|
||||||
|
nested_dict[target_key] = new_value
|
||||||
|
return nested_dict
|
||||||
|
|
||||||
|
# 处理crud,返回columns
|
||||||
|
def __handle_crud(self):
|
||||||
|
result = self.__get_field_attribute()
|
||||||
|
columns = dict()
|
||||||
|
for item in result:
|
||||||
|
key = item.get('key')
|
||||||
|
title = item.get('title')
|
||||||
|
type = item.get('type')
|
||||||
|
columns[key] = {
|
||||||
|
"title": title,
|
||||||
|
"key": key,
|
||||||
|
"type": type
|
||||||
|
}
|
||||||
|
# 对自定义的crud配置合并
|
||||||
|
if self.custom_crud_json and isinstance(self.custom_crud_json,dict):
|
||||||
|
columns = columns | self.custom_crud_json
|
||||||
|
# 对curd进行修改配置
|
||||||
|
if self.crud_update_key_value and isinstance(self.crud_update_key_value,dict):
|
||||||
|
for key, value in self.crud_update_key_value.items():
|
||||||
|
columns = self.__update_nested_dict(columns,key,value)
|
||||||
|
return columns
|
||||||
|
@action(methods=['get'], detail=False,permission_classes=[AllowAny])
|
||||||
|
def init_crud(self, request):
|
||||||
|
self.permission_classes = [AllowAny]
|
||||||
|
columns = self.__handle_crud()
|
||||||
|
expose = "({expose,dict})=>{"
|
||||||
|
ret = "return {"
|
||||||
|
res = "}}"
|
||||||
|
data = f"""{expose}
|
||||||
|
{ret}
|
||||||
|
columns:{columns}
|
||||||
|
{res}
|
||||||
|
"""
|
||||||
|
return DetailResponse(data=data)
|
||||||
@@ -81,6 +81,7 @@ export const createCrudOptions = function ({ crudExpose, menuButtonRef }: { crud
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
rowHandle: {
|
rowHandle: {
|
||||||
|
fixed: "right",
|
||||||
width: 310,
|
width: 310,
|
||||||
buttons: {
|
buttons: {
|
||||||
custom: {
|
custom: {
|
||||||
@@ -103,7 +104,7 @@ export const createCrudOptions = function ({ crudExpose, menuButtonRef }: { crud
|
|||||||
menuButtonRef.value.initGet();
|
menuButtonRef.value.initGet();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
columns: {
|
columns: {
|
||||||
_index: {
|
_index: {
|
||||||
@@ -244,7 +245,7 @@ export const createCrudOptions = function ({ crudExpose, menuButtonRef }: { crud
|
|||||||
is_catalog: {
|
is_catalog: {
|
||||||
title: '是否目录',
|
title: '是否目录',
|
||||||
column: {
|
column: {
|
||||||
width: 60,
|
width: 100,
|
||||||
},
|
},
|
||||||
type: 'dict-switch',
|
type: 'dict-switch',
|
||||||
dict: dict({
|
dict: dict({
|
||||||
@@ -443,7 +444,7 @@ export const createCrudOptions = function ({ crudExpose, menuButtonRef }: { crud
|
|||||||
visible: {
|
visible: {
|
||||||
title: '侧边可见',
|
title: '侧边可见',
|
||||||
column: {
|
column: {
|
||||||
width: 60,
|
width: 100,
|
||||||
},
|
},
|
||||||
search: {
|
search: {
|
||||||
show: true,
|
show: true,
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ export const createCrudOptions = function ({crudExpose,rolePermission}: {crudExp
|
|||||||
delRequest,
|
delRequest,
|
||||||
},
|
},
|
||||||
rowHandle: {
|
rowHandle: {
|
||||||
|
//固定右侧
|
||||||
|
fixed: "right",
|
||||||
|
width:310,
|
||||||
buttons: {
|
buttons: {
|
||||||
custom: {
|
custom: {
|
||||||
text: "权限配置",
|
text: "权限配置",
|
||||||
|
|||||||
Reference in New Issue
Block a user