views.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. from rest_framework import viewsets
  2. from .models import ListModel, TypeListModel
  3. from . import serializers
  4. from utils.page import MyPageNumberPagination
  5. from rest_framework.filters import OrderingFilter
  6. from django_filters.rest_framework import DjangoFilterBackend
  7. from rest_framework.response import Response
  8. from .filter import Filter, TypeFilter
  9. from rest_framework.exceptions import APIException
  10. from .serializers import FileRenderSerializer
  11. from django.http import StreamingHttpResponse
  12. from .files import FileRenderCN, FileRenderEN
  13. from rest_framework.settings import api_settings
  14. from rest_framework import permissions
  15. from staff.models import ListModel as staff
  16. from utils.md5 import Md5
  17. import random
  18. from django.contrib.auth.models import User
  19. from .models import Role, Permission # 新增角色和权限模型导入
  20. class APIViewSet(viewsets.ModelViewSet):
  21. """
  22. retrieve:
  23. Response a data list(get)
  24. list:
  25. Response a data list(all)
  26. create:
  27. Create a data line(post)
  28. delete:
  29. Delete a data line(delete)
  30. partial_update:
  31. Partial_update a data(patch:partial_update)
  32. update:
  33. Update a data(put:update)
  34. """
  35. pagination_class = MyPageNumberPagination
  36. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  37. ordering_fields = ['id', "create_time", "update_time", ]
  38. filter_class = Filter
  39. def list(self, request, *args, **kwargs):
  40. # staff_name = str(request.GET.get('staff_name'))
  41. # check_code = request.GET.get('check_code')
  42. # if staff_name == None and check_code == None:
  43. # return super().list(request, *args, **kwargs)
  44. # elif staff_name != None and check_code == None:
  45. # return super().list(request, *args, **kwargs)
  46. # else:
  47. # staff_name_obj = ListModel.objects.filter(openid=self.request.auth.openid, staff_name=staff_name,
  48. # is_delete=False).first()
  49. # if staff_name_obj is None:
  50. # raise APIException({"detail": "用户名不存在"})
  51. # elif staff_name_obj.is_lock is True:
  52. # raise APIException({"detail": "用户已被锁定,请联系管理员"})
  53. # elif staff_name_obj.error_check_code_counter == 3:
  54. # staff_name_obj.is_lock = True
  55. # staff_name_obj.error_check_code_counter = 0
  56. # staff_name_obj.save()
  57. # raise APIException({"detail": "用户已被锁定,请联系管理员"})
  58. # if type(check_code) == str:
  59. # check_code = int(check_code)
  60. # if check_code != None:
  61. # if staff_name_obj.check_code != check_code:
  62. # staff_name_obj.error_check_code_counter = int(staff_name_obj.error_check_code_counter) + 1
  63. # staff_name_obj.save()
  64. # raise APIException({"detail": "验证码错误"})
  65. # else:
  66. # staff_name_obj.error_check_code_counter = 0
  67. # staff_name_obj.save()
  68. # return super().list(request, *args, **kwargs)
  69. # else:
  70. return super().list(request, *args, **kwargs)
  71. def get_project(self):
  72. try:
  73. id = self.kwargs.get('pk')
  74. return id
  75. except:
  76. return None
  77. def get_queryset(self):
  78. id = self.get_project()
  79. if self.request.user:
  80. if id is None:
  81. return ListModel.objects.filter(is_delete=False)
  82. else:
  83. return ListModel.objects.filter(id=id, is_delete=False)
  84. else:
  85. return ListModel.objects.none()
  86. def get_serializer_class(self):
  87. staff_type = ListModel.objects.filter(openid=self.request.auth.openid, is_delete=False).first().staff_type
  88. if staff_type not in ['admin', '主管', '管理员','经理']:
  89. if self.action in ['list', 'retrieve', 'destroy']:
  90. return serializers.userStaffGetSerializer
  91. elif self.action in ['create']:
  92. return serializers.userStaffPostSerializer
  93. elif self.action in ['update']:
  94. return serializers.userStaffUpdateSerializer
  95. elif self.action in ['partial_update']:
  96. return serializers.userStaffPartialUpdateSerializer
  97. else:
  98. return self.http_method_not_allowed(request=self.request)
  99. else:
  100. if self.action in ['list', 'retrieve', 'destroy']:
  101. return serializers.StaffGetSerializer
  102. elif self.action in ['create']:
  103. return serializers.StaffPostSerializer
  104. elif self.action in ['update']:
  105. return serializers.StaffUpdateSerializer
  106. elif self.action in ['partial_update']:
  107. return serializers.StaffPartialUpdateSerializer
  108. else:
  109. return self.http_method_not_allowed(request=self.request)
  110. def create(self, request, *args, **kwargs):
  111. data = self.request.data
  112. data['openid'] = self.request.auth.openid
  113. # 检查角色是否存在
  114. role_name = data.get('role')
  115. if role_name:
  116. role, created = Role.objects.get_or_create(name=role_name)
  117. data['role'] = role.id
  118. if ListModel.objects.filter(openid=data['openid'], staff_name=data['staff_name'], is_delete=False).exists():
  119. raise APIException({"detail": "Data exists"})
  120. else:
  121. app_code = Md5.md5(data['staff_name'] + '1')
  122. data['appid'] = app_code
  123. check_code = random.randint(1000, 9999)
  124. data['check_code'] = check_code
  125. # 创建用户
  126. user = User.objects.create_user(
  127. username=str(data['staff_name']),
  128. password=str(check_code)
  129. )
  130. serializer = self.get_serializer(data=data)
  131. serializer.is_valid(raise_exception=True)
  132. serializer.save()
  133. headers = self.get_success_headers(serializer.data)
  134. return Response(serializer.data, status=200, headers=headers)
  135. def update(self, request, pk):
  136. qs = self.get_object()
  137. if qs.openid != self.request.auth.openid:
  138. creator = ListModel.objects.filter(openid=self.request.auth.openid, is_delete=False)
  139. raise APIException({"detail": "该用户不是您创建的,不能修改"})
  140. else:
  141. data = self.request.data
  142. # 更新角色
  143. role_name = data.get('role')
  144. if role_name:
  145. role, created = Role.objects.get_or_create(name=role_name)
  146. data['role'] = role.id
  147. serializer = self.get_serializer(qs, data=data)
  148. serializer.is_valid(raise_exception=True)
  149. serializer.save()
  150. headers = self.get_success_headers(serializer.data)
  151. return Response(serializer.data, status=200, headers=headers)
  152. def partial_update(self, request, pk):
  153. qs = self.get_object()
  154. if qs.openid != self.request.auth.openid:
  155. raise APIException({"detail": "Cannot Update Data Which Not Yours"})
  156. else:
  157. data = self.request.data
  158. # 更新角色
  159. role_name = data.get('role')
  160. if role_name:
  161. role, created = Role.objects.get_or_create(name=role_name)
  162. data['role'] = role.id
  163. serializer = self.get_serializer(qs, data=data, partial=True)
  164. serializer.is_valid(raise_exception=True)
  165. serializer.save()
  166. headers = self.get_success_headers(serializer.data)
  167. return Response(serializer.data, status=200, headers=headers)
  168. def destroy(self, request, pk):
  169. qs = self.get_object()
  170. if qs.openid != self.request.auth.openid:
  171. raise APIException({"detail": "Cannot Delete Data Which Not Yours"})
  172. else:
  173. qs.is_delete = True
  174. qs.save()
  175. serializer = self.get_serializer(qs, many=False)
  176. headers = self.get_success_headers(serializer.data)
  177. return Response(serializer.data, status=200, headers=headers)
  178. class RoleViewSet(viewsets.ModelViewSet):
  179. """角色管理API"""
  180. queryset = Role.objects.all()
  181. serializer_class = serializers.RoleSerializer
  182. pagination_class = MyPageNumberPagination
  183. filter_backends = [DjangoFilterBackend, OrderingFilter]
  184. ordering_fields = ['id', "name"]
  185. def get_queryset(self):
  186. return Role.objects.all()
  187. class PermissionViewSet(viewsets.ModelViewSet):
  188. """权限管理API"""
  189. queryset = Permission.objects.all()
  190. serializer_class = serializers.PermissionSerializer
  191. # pagination_class = MyPageNumberPagination
  192. filter_backends = [DjangoFilterBackend, OrderingFilter]
  193. ordering_fields = ['id', "page"]
  194. def get_queryset(self):
  195. role = self.request.query_params.get('role')
  196. if role:
  197. return Permission.objects.filter(role__name=role)
  198. return Permission.objects.all()
  199. class RolePermissionViewSet(viewsets.ViewSet):
  200. """角色权限配置API"""
  201. def list(self, request):
  202. """获取所有角色类型"""
  203. roles = Role.objects.values_list('name', flat=True).distinct()
  204. return Response(list(roles))
  205. def retrieve(self, request, pk=None):
  206. """获取特定角色的权限配置"""
  207. try:
  208. role = Role.objects.get(name=pk)
  209. serializer = serializers.RoleGETSerializer(role)
  210. return Response(serializer.data)
  211. except Role.DoesNotExist:
  212. return Response({"error": "Role not found"}, status=404)
  213. def update(self, request, pk=None):
  214. """更新角色权限"""
  215. try:
  216. role = Role.objects.get(name=pk)
  217. permissions_data = request.data.get('permissions', [])
  218. # 清除现有权限
  219. role.permissions.clear()
  220. # 添加新权限
  221. for perm_data in permissions_data:
  222. perm, created = Permission.objects.get_or_create(
  223. page=perm_data['page'],
  224. component=perm_data.get('component'),
  225. defaults={'enabled': perm_data['enabled']}
  226. )
  227. role.permissions.add(perm)
  228. return Response({"message": "Permissions updated successfully"})
  229. except Role.DoesNotExist:
  230. return Response({"error": "Role not found"}, status=404)
  231. class RolePagePermissionViewSet(viewsets.ViewSet):
  232. """角色权限配置API"""
  233. def list(self, request):
  234. """获取所有角色类型"""
  235. roles = Role.objects.values_list('name', flat=True).distinct()
  236. return Response(list(roles))
  237. def retrieve(self, request, pk=None):
  238. """获取特定角色的权限配置"""
  239. try:
  240. role = Role.objects.get(name=pk)
  241. serializer = serializers.RolePageGETSerializer(role)
  242. return Response(serializer.data)
  243. except Role.DoesNotExist:
  244. return Response({"error": "Role not found"}, status=404)
  245. def get_page_permissions(self, request, pk=None):
  246. """获取特定角色的页面访问权限配置"""
  247. try:
  248. role = Role.objects.get(name=pk)
  249. primary_page = request.data.get('primary_page')
  250. if primary_page:
  251. fliterpermissions= role.permissions.filter(primary_page=primary_page)
  252. serializer = self.get_permissions_group(fliterpermissions)
  253. return Response(serializer)
  254. serializer = self.get_permissions_group(role.permissions.all())
  255. return Response(serializer)
  256. except Role.DoesNotExist:
  257. return Response({"error": "Role not found"}, status=404)
  258. def get_permissions_group(self, permissions):
  259. # 获取角色关联的所有权限并预取数据
  260. # 按page字段分组,只处理component为null的权限
  261. page_access = {}
  262. for perm in permissions:
  263. # 只处理页面访问权限(component为null)
  264. if perm.component is None:
  265. page_access[perm.page] = perm.enabled
  266. # 转换为前端需要的格式
  267. return [{"page": page, "enabled": enabled} for page, enabled in page_access.items()]
  268. class RolePageComponentPermissionViewSet(viewsets.ViewSet):
  269. """角色权限配置API"""
  270. def get_page_component_permissions(self, request, pk=None):
  271. """获取特定角色的页面访问权限配置"""
  272. try:
  273. role = Role.objects.get(name=pk)
  274. page = request.data.get('page')
  275. if page:
  276. fliterpermissions= role.permissions.filter(page=page)
  277. serializer = self.get_permissions_group(fliterpermissions)
  278. return Response(serializer)
  279. serializer = self.get_permissions_group(role.permissions.all())
  280. return Response(serializer)
  281. except Role.DoesNotExist:
  282. return Response({"error": "Role not found"}, status=404)
  283. def get_permissions_group(self, permissions):
  284. # 获取角色关联的所有权限并预取数据
  285. page_access = {}
  286. for perm in permissions:
  287. if perm.component is not None:
  288. page_access[perm.component] = perm.enabled
  289. # 转换为前端需要的格式
  290. return [{"component": component, "enabled": enabled} for component, enabled in page_access.items()]
  291. class TypeAPIViewSet(viewsets.ModelViewSet):
  292. """
  293. list:
  294. Response a data list(all)
  295. """
  296. pagination_class = MyPageNumberPagination
  297. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  298. ordering_fields = ['id', "create_time", "update_time", ]
  299. filter_class = TypeFilter
  300. def get_queryset(self):
  301. if self.request.user:
  302. return TypeListModel.objects.filter(openid='init_data')
  303. else:
  304. return TypeListModel.objects.none()
  305. def get_serializer_class(self):
  306. if self.action in ['list']:
  307. return serializers.StaffTypeGetSerializer
  308. else:
  309. return self.http_method_not_allowed(request=self.request)
  310. class FileDownloadView(viewsets.ModelViewSet):
  311. renderer_classes = (FileRenderCN,) + tuple(api_settings.DEFAULT_RENDERER_CLASSES)
  312. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  313. ordering_fields = ['id', "create_time", "update_time", ]
  314. filter_class = Filter
  315. def get_project(self):
  316. try:
  317. id = self.kwargs.get('pk')
  318. return id
  319. except:
  320. return None
  321. def get_queryset(self):
  322. id = self.get_project()
  323. if self.request.user:
  324. if id is None:
  325. return ListModel.objects.filter(openid=self.request.auth.openid, is_delete=False)
  326. else:
  327. return ListModel.objects.filter(openid=self.request.auth.openid, id=id, is_delete=False)
  328. else:
  329. return ListModel.objects.none()
  330. def get_serializer_class(self):
  331. if self.action in ['list']:
  332. return serializers.FileRenderSerializer
  333. else:
  334. return self.http_method_not_allowed(request=self.request)
  335. def get_lang(self, data):
  336. lang = self.request.META.get('HTTP_LANGUAGE')
  337. if lang:
  338. if lang == 'zh-hans':
  339. return FileRenderCN().render(data)
  340. else:
  341. return FileRenderEN().render(data)
  342. else:
  343. return FileRenderEN().render(data)
  344. def list(self, request, *args, **kwargs):
  345. from datetime import datetime
  346. dt = datetime.now()
  347. data = (
  348. FileRenderSerializer(instance).data
  349. for instance in self.filter_queryset(self.get_queryset())
  350. )
  351. renderer = self.get_lang(data)
  352. response = StreamingHttpResponse(
  353. renderer,
  354. content_type="text/csv"
  355. )
  356. response['Content-Disposition'] = "attachment; filename='staff_{}.csv'".format(
  357. str(dt.strftime('%Y%m%d%H%M%S%f')))
  358. return response