system_config.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. # -*- coding: utf-8 -*-
  2. """
  3. @author: Allen
  4. @Created on: 2023/10/18
  5. @Remark: 系统配置
  6. """
  7. import django_filters
  8. from django.db import connection
  9. from django.db.models import Q
  10. from django_filters.rest_framework import BooleanFilter
  11. from rest_framework import serializers
  12. from rest_framework.views import APIView
  13. from application import dispatch
  14. from application.websocketConfig import websocket_push
  15. from dvadmin.system.models import SystemConfig
  16. from dvadmin.utils.json_response import DetailResponse, SuccessResponse, ErrorResponse
  17. from dvadmin.utils.models import get_all_models_objects
  18. from dvadmin.utils.serializers import CustomModelSerializer
  19. from dvadmin.utils.validator import CustomValidationError
  20. from dvadmin.utils.viewset import CustomModelViewSet
  21. class SystemConfigCreateSerializer(CustomModelSerializer):
  22. """
  23. 系统配置-新增时使用-序列化器
  24. """
  25. form_item_type_label = serializers.CharField(source='get_form_item_type_display', read_only=True)
  26. class Meta:
  27. model = SystemConfig
  28. fields = "__all__"
  29. read_only_fields = ["id"]
  30. def validate_key(self, value):
  31. """
  32. 验证key是否允许重复
  33. parent为空时不允许重复,反之允许
  34. """
  35. instance = SystemConfig.objects.filter(key=value, parent__isnull=True).exists()
  36. if instance:
  37. raise CustomValidationError('已存在相同变量名')
  38. return value
  39. class SystemConfigInitSerializer(CustomModelSerializer):
  40. """
  41. 初始化获取数信息(用于生成初始化json文件)
  42. """
  43. children = serializers.SerializerMethodField()
  44. def get_children(self, obj: SystemConfig):
  45. data = []
  46. instance = SystemConfig.objects.filter(parent_id=obj.id)
  47. if instance:
  48. serializer = SystemConfigInitSerializer(instance=instance, many=True)
  49. data = serializer.data
  50. return data
  51. def save(self, **kwargs):
  52. instance = super().save(**kwargs)
  53. children = self.initial_data.get('children')
  54. # 菜单表
  55. if children:
  56. for data in children:
  57. data['parent'] = instance.id
  58. filter_data = {
  59. "key": data['key'],
  60. "parent": data['parent']
  61. }
  62. instance_obj = SystemConfig.objects.filter(**filter_data).first()
  63. if instance_obj and not self.initial_data.get('reset'):
  64. continue
  65. serializer = SystemConfigInitSerializer(instance_obj, data=data, request=self.request)
  66. serializer.is_valid(raise_exception=True)
  67. serializer.save()
  68. return instance
  69. class Meta:
  70. model = SystemConfig
  71. fields = ['parent', 'title', 'key', 'value', 'sort', 'status', 'data_options', 'form_item_type', 'rule',
  72. 'placeholder', 'setting', 'creator', 'dept_belong_id', 'children']
  73. read_only_fields = ["id"]
  74. extra_kwargs = {
  75. 'creator': {'write_only': True},
  76. 'dept_belong_id': {'write_only': True}
  77. }
  78. class SystemConfigSerializer(CustomModelSerializer):
  79. """
  80. 系统配置-序列化器
  81. """
  82. form_item_type_label = serializers.CharField(source='get_form_item_type_display', read_only=True)
  83. class Meta:
  84. model = SystemConfig
  85. fields = "__all__"
  86. read_only_fields = ["id"]
  87. class SystemConfigChinldernSerializer(CustomModelSerializer):
  88. """
  89. 系统配置子级-序列化器
  90. """
  91. chinldern = serializers.SerializerMethodField()
  92. form_item_type_label = serializers.CharField(source='get_form_item_type_display', read_only=True)
  93. def get_chinldern(self, instance):
  94. queryset = SystemConfig.objects.filter(parent=instance)
  95. serializer = SystemConfigSerializer(queryset, many=True)
  96. return serializer.data
  97. class Meta:
  98. model = SystemConfig
  99. fields = "__all__"
  100. read_only_fields = ["id"]
  101. class SystemConfigListSerializer(CustomModelSerializer):
  102. """
  103. 系统配置下模块的保存-序列化器
  104. """
  105. def update(self, instance, validated_data):
  106. instance_mapping = {obj.id: obj for obj in instance}
  107. data_mapping = {item['id']: item for item in validated_data}
  108. for obj_id, data in data_mapping.items():
  109. instance_obj = instance_mapping.get(obj_id, None)
  110. if instance_obj is None:
  111. return SystemConfig.objects.create(**data)
  112. else:
  113. return instance_obj.objects.update(**data)
  114. class Meta:
  115. model = SystemConfig
  116. fields = "__all__"
  117. read_only_fields = ["id"]
  118. class SystemConfigSaveSerializer(serializers.Serializer):
  119. class Meta:
  120. read_only_fields = ["id"]
  121. list_serializer_class = SystemConfigListSerializer
  122. class SystemConfigFilter(django_filters.rest_framework.FilterSet):
  123. """
  124. 过滤器
  125. """
  126. parent__isnull = BooleanFilter(field_name='parent', lookup_expr="isnull")
  127. class Meta:
  128. model = SystemConfig
  129. fields = ['id', 'parent', 'status', 'parent__isnull']
  130. class SystemConfigViewSet(CustomModelViewSet):
  131. """
  132. 系统配置接口
  133. """
  134. queryset = SystemConfig.objects.order_by('sort', 'create_datetime')
  135. serializer_class = SystemConfigChinldernSerializer
  136. create_serializer_class = SystemConfigCreateSerializer
  137. retrieve_serializer_class = SystemConfigChinldernSerializer
  138. # filter_fields = ['id','parent']
  139. filter_class = SystemConfigFilter
  140. def save_content(self, request):
  141. body = request.data
  142. data_mapping = {item['id']: item for item in body}
  143. for obj_id, data in data_mapping.items():
  144. instance_obj = SystemConfig.objects.filter(id=obj_id).first()
  145. if instance_obj is None:
  146. # return SystemConfig.objects.create(**data)
  147. serializer = SystemConfigCreateSerializer(data=data)
  148. else:
  149. serializer = SystemConfigCreateSerializer(instance_obj, data=data)
  150. if serializer.is_valid(raise_exception=True):
  151. serializer.save()
  152. websocket_push("dvadmin", message={"sender": 'system', "contentType": 'SYSTEM',
  153. "content": '系统配置有变化~', "systemConfig": True})
  154. return DetailResponse(msg="保存成功")
  155. def get_association_table(self, request):
  156. """
  157. 获取所有的model及字段信息
  158. """
  159. res = [ele.get('table') for ele in get_all_models_objects().values()]
  160. return DetailResponse(msg="获取成功", data=res)
  161. def get_table_data(self, request, pk):
  162. """
  163. 动态获取关联表的数据
  164. """
  165. instance = SystemConfig.objects.filter(id=pk).first()
  166. if instance is None:
  167. return ErrorResponse(msg="查询出错了~")
  168. setting = instance.setting
  169. if setting is None:
  170. return ErrorResponse(msg="查询出错了~")
  171. table = setting.get('table') # 获取model名
  172. model = get_all_models_objects(table).get("object", {})
  173. # 自己判断一下不存在
  174. queryset = model.objects.values()
  175. body = request.query_params
  176. search_value = body.get('search', None)
  177. if search_value:
  178. search_fields = setting.get('searchField')
  179. filters = Q()
  180. filters.connector = 'OR'
  181. for item in search_fields:
  182. filed = '{0}__icontains'.format(item.get('field'))
  183. filters.children.append((filed, search_value))
  184. queryset = model.objects.filter(filters).values()
  185. page = self.paginate_queryset(queryset)
  186. if page is not None:
  187. return self.get_paginated_response(queryset)
  188. return SuccessResponse(msg="获取成功", data=queryset, total=len(queryset))
  189. def get_relation_info(self, request):
  190. """
  191. 查询关联的模板信息
  192. """
  193. body = request.query_params
  194. var_name = body.get('varName', None)
  195. table = body.get('table', None)
  196. instance = SystemConfig.objects.filter(key=var_name, setting__table=table).first()
  197. if instance is None:
  198. return ErrorResponse(msg="未获取到关联信息")
  199. relation_id = body.get('relationIds', None)
  200. relationIds = []
  201. if relation_id is None:
  202. return ErrorResponse(msg="未获取到关联信息")
  203. if instance.form_item_type in [13]:
  204. relationIds = [relation_id]
  205. elif instance.form_item_type in [14]:
  206. relationIds = relation_id.split(',')
  207. queryset = SystemConfig.objects.filter(value__in=relationIds).first()
  208. if queryset is None:
  209. return ErrorResponse(msg="未获取到关联信息")
  210. serializer = SystemConfigChinldernSerializer(queryset.parent)
  211. return DetailResponse(msg="查询成功", data=serializer.data)
  212. class InitSettingsViewSet(APIView):
  213. """
  214. 获取初始化配置
  215. """
  216. authentication_classes = []
  217. permission_classes = []
  218. def filter_system_config_values(self, data: dict):
  219. """
  220. 过滤系统初始化配置
  221. :param data:
  222. :return:
  223. """
  224. if not self.request.query_params.get('key', ''):
  225. return data
  226. new_data = {}
  227. for key in self.request.query_params.get('key', '').split('|'):
  228. if key:
  229. new_data.update(**dict(filter(lambda x: x[0].startswith(key), data.items())))
  230. return new_data
  231. def get(self, request):
  232. data = dispatch.get_system_config()
  233. if not data:
  234. dispatch.refresh_system_config()
  235. data = dispatch.get_system_config()
  236. # 不返回后端专用配置
  237. backend_config = [f"{ele.get('parent__key')}.{ele.get('key')}" for ele in
  238. SystemConfig.objects.filter(status=False, parent_id__isnull=False).values('parent__key',
  239. 'key')]
  240. data = dict(filter(lambda x: x[0] not in backend_config, data.items()))
  241. if hasattr(connection, 'tenant'):
  242. data['schema_name'] = connection.tenant.schema_name
  243. return DetailResponse(data=data)