diff --git a/backend/dvadmin/utils/crud_mixin.py b/backend/dvadmin/utils/crud_mixin.py new file mode 100644 index 0000000..9b4c018 --- /dev/null +++ b/backend/dvadmin/utils/crud_mixin.py @@ -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) diff --git a/web/src/views/system/menu/crud.tsx b/web/src/views/system/menu/crud.tsx index 7040f6b..539d479 100644 --- a/web/src/views/system/menu/crud.tsx +++ b/web/src/views/system/menu/crud.tsx @@ -81,6 +81,7 @@ export const createCrudOptions = function ({ crudExpose, menuButtonRef }: { crud }, }, rowHandle: { + fixed: "right", width: 310, buttons: { custom: { @@ -103,7 +104,7 @@ export const createCrudOptions = function ({ crudExpose, menuButtonRef }: { crud menuButtonRef.value.initGet(); }, }, - }, + } }, columns: { _index: { @@ -244,7 +245,7 @@ export const createCrudOptions = function ({ crudExpose, menuButtonRef }: { crud is_catalog: { title: '是否目录', column: { - width: 60, + width: 100, }, type: 'dict-switch', dict: dict({ @@ -443,7 +444,7 @@ export const createCrudOptions = function ({ crudExpose, menuButtonRef }: { crud visible: { title: '侧边可见', column: { - width: 60, + width: 100, }, search: { show: true, diff --git a/web/src/views/system/role/curd.tsx b/web/src/views/system/role/curd.tsx index bfc1b00..330b5f7 100644 --- a/web/src/views/system/role/curd.tsx +++ b/web/src/views/system/role/curd.tsx @@ -31,6 +31,9 @@ export const createCrudOptions = function ({crudExpose,rolePermission}: {crudExp delRequest, }, rowHandle: { + //固定右侧 + fixed: "right", + width:310, buttons: { custom: { text: "权限配置",