from apps.third.filters import TDeviceFilterSet, DoorAuthFilter from apps.third.models import BltBind, TDevice, Tlog, DoorAuth from apps.third.serializers import BindAreaSerializer, BltBindCreateSerializer, BltQuerySerializer, BltSerializer, LabelLocationSerializer, TDeviceSerializer, TDeviceUpdateSerializer, TlogSerializer, DoorAuthSerializer from apps.utils.viewsets import CustomGenericViewSet from rest_framework.mixins import ListModelMixin, CreateModelMixin from apps.third.dahua import dhClient from apps.third.xunxi import xxClient from apps.third.speaker import spClient from apps.third.tapis import xxapis, dhapis, spapis from rest_framework.response import Response from rest_framework.serializers import Serializer from rest_framework.decorators import action from apps.am.models import Area from rest_framework.views import APIView from rest_framework.exceptions import ParseError from django.db import transaction from rest_framework.mixins import ListModelMixin, CreateModelMixin, DestroyModelMixin, UpdateModelMixin from apps.utils.serializers import PkSerializer from apps.hrm.serializers import EmployeeShortSerializer from apps.hrm.models import Employee from django.core.cache import cache class BltViewSet(CustomGenericViewSet): """定位标签列表 定位标签列表 """ queryset = TDevice.objects.filter(type=TDevice.DEVICE_BLT) serializer_class = TDeviceSerializer @action(methods=['get'], detail=False, perms_map={'get': '*'}) def count_bind(self, request): """统计绑定定位卡人/设备数 统计绑定定位卡人/设备数 """ qs = self.queryset.exclude(employee=None) ret = {} ret['total'] = qs.count() ret['count_employee'] = qs.filter(employee__type='employee').count() ret['count_remployee'] = qs.filter(employee__type='remployee').count() ret['count_visitor'] = qs.filter(employee__type='visitor').count() ret['count_driver'] = qs.filter(employee__type='driver').count() return Response(ret) @action(methods=['get'], detail=False, perms_map={'get': '*'}) def count_now(self, request): """统计在厂且绑定标签数 统计在厂且绑定标签数 """ json = { "pageNum": 1, "numPerPage": 2000, "online": "online" } _, res = xxClient.request(**xxapis['blt_list'], json=json) ret = {} ret['total_blt'] = res['totalCount'] blt_list = res['recordList'] macs = [] for i in blt_list: if 'online' in i and i['online']: macs.append(i['mac']) qs = self.queryset.filter(code__in=macs).exclude(employee=None) ret['total'] = qs.count() ret['count_employee'] = qs.filter(employee__type='employee').count() ret['count_remployee'] = qs.filter(employee__type='remployee').count() ret['count_visitor'] = qs.filter(employee__type='visitor').count() ret['count_driver'] = qs.filter(employee__type='driver').count() return Response(ret) @action(methods=['post'], detail=False, perms_map={'post': 'blt.all'}, serializer_class=BltQuerySerializer, logging_methods=[]) def all(self, request): """全部在线标签列表信息 全部在线标签列表信息 """ data = request.data area = None if data.get('area', None): try: area = Area.objects.get(id=data['area']) railId = area.third_info['xx_rail']['id'] except Exception: raise ParseError('围栏未绘制') json = { "railId": railId, "type": "" } _, res = xxClient.request(**xxapis['rail_ibeacon_list'], json=json) else: json = { "pageNum": 1, "numPerPage": 2000, "online": "online" } _, res = xxClient.request(**xxapis['blt_list'], json=json) count_people = 0 blt_list = res['recordList'] macs = [] for i in blt_list: if 'online' in i and i['online'] is False: pass else: if 'userId' in i: i['mac'] = i['userId'] macs.append(i['mac']) qs = self.queryset.filter(code__in=macs).exclude(employee=None) if data.get('depts', []): qs = qs.filter(employee__belong_dept=data['depts']) qs_data = BltSerializer(instance=qs, many=True).data qs_dict = {} for i in qs_data: qs_dict[i['code']] = i blt_list_n = [] for i in blt_list: i['my_info'] = {} if i['mac'] in qs_dict: i['my_info'] = qs_dict[i['mac']] blt_list_n.append(i) if area: # 更新区域下的总人数 count_people = qs.filter(obj_cate='people').count() area.count_people = count_people area.save() return Response(blt_list_n) class TDeviceViewSet(ListModelMixin, UpdateModelMixin, DestroyModelMixin, CustomGenericViewSet): """ 三方设备接口 """ perms_map = {'get': '*', 'put': 'tdevice.update', 'delete': 'tdevice.delete'} queryset = TDevice.objects.all() serializer_class = TDeviceSerializer update_serializer_class = TDeviceUpdateSerializer ordering = ['-create_time'] filterset_class = TDeviceFilterSet select_related_fields = ['employee', 'area', 'employee__post', 'employee__belong_dept'] def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset()) page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) else: serializer = self.get_serializer(queryset, many=True) data = serializer.data typex = self.request.query_params.get('type', None) if typex == str(TDevice.DEVICE_BLT): # 如果是定位标签加载实时的三方信息 macs = [] for i in data: macs.append(i['code']) json = { "macList": macs } _, res = xxClient.request(**xxapis['blt_info'], json=json) macs_dict = {} for i in res['success']: macs_dict[i['mac']] = i for i in res['error']: macs_dict[i['mac']] = i for i in data: i['third_info'] = macs_dict.get(i['code'], {}) elif typex == str(TDevice.DEVICE_VCHANNEL): codes = [i['code'] for i in data] json = { 'unitTypeList': ["1"], 'includeSubOwnerCodeFlag': True, 'channelCodeList': codes, 'pageSize': len(codes) } _, res = dhClient.request(**dhapis['channel_list'], json=json) codes_dict = {} for i in res['pageData']: codes_dict[i['channelCode']] = i for i in data: i['third_info'] = codes_dict.get(i['code'], {}) if page is not None: return self.get_paginated_response(data) else: return Response(data) # @action(methods=['post'], detail=False, perms_map={'post': '*'}, # serializer_class=PkSerializer) # def start_mtask(self, request): # """开启视频算法监控 # 开启视频算法监控 # """ # sr = PkSerializer(data=request.data) # sr.is_valid(raise_exception=True) # vdata = sr.validated_data # from apps.ecm.tasks import monitor_check # monitor_check(vdata) # return Response() # @action(methods=['post'], detail=False, perms_map={'post': '*'}, # serializer_class=PkSerializer) # def stop_mtask(self, request): # """停止视频算法监控 # 停止视频算法监控 # """ # sr = PkSerializer(data=request.data) # sr.is_valid(raise_exception=True) # vdata = sr.validated_data # vcids = TDevice.objects.filter(id__in=vdata, type=TDevice.DEVICE_VCHANNEL).values_list('id', flat=True) # for id in vcids: # ckey = 'vchannel_' + id # cache.delete(ckey) # return Response() @action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=Serializer) @transaction.atomic def blt_sync(self, request): """同步标签mac至平台 同步标签mac至平台 """ json = { "pageNum": 1, "numPerPage": 1000 } _, res = xxClient.request(**xxapis['blt_list'], json=json) blt_list = res['recordList'] for i in blt_list: TDevice.objects.get_or_create(code=i['mac'], defaults={ "code": i['mac'], "type": TDevice.DEVICE_BLT}) return Response() @action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=Serializer) @transaction.atomic def speaker_sync(self, request): """同步喇叭通道 同步喇叭通道 """ params = { "page": 1, "pageSize": 1000 } _, res = spClient.request(**spapis['device_list'], params=params) rows = res['rows'] t_l = [] for i in rows: t_l.append(i['sn']) td = TDevice.objects.filter(code=i['sn']).first() if td: pass else: td = TDevice(code=i['sn'], type=TDevice.DEVICE_SPEAKER) td.name = i['name'] td.save() TDevice.objects.filter(type=TDevice.DEVICE_SPEAKER).exclude( code__in=t_l).delete() # 移除不需要的 return Response() @action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=Serializer) def vchannel_sync(self, request): """同步视频通道 同步视频通道 """ json = { "pageNum": 1, "pageSize": 1000, 'unitTypeList': ["1"], 'includeSubOwnerCodeFlag': True } _, res = dhClient.request(**dhapis['channel_list'], json=json) if res.get('pageData', None): t_l = [] for i in res['pageData']: t_l.append(i['channelCode']) td = TDevice.objects.filter(code=i['channelCode']).first() if td: pass else: td = TDevice(code=i['channelCode'], type=TDevice.DEVICE_VCHANNEL) td.name = i['channelName'] td.save() TDevice.objects.filter(type=TDevice.DEVICE_VCHANNEL).exclude( code__in=t_l).delete() return Response() @action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=Serializer) @transaction.atomic def dchannel_sync(self, request): """同步门禁通道 同步门禁通道 """ json = { "pageNum": 1, "pageSize": 1000, 'unitTypeList': ["7"], 'includeSubOwnerCodeFlag': True } _, res = dhClient.request(**dhapis['channel_list'], json=json) if res.get('pageData', None): for i in res['pageData']: td = TDevice.objects.filter(code=i['channelCode']).first() if td: pass else: td = TDevice(code=i['channelCode'], type=TDevice.DEVICE_DCHANNEL) td.name = i['channelName'] # td.access_list = ['employee', 'remployee', 'visitor'] td.save() return Response() @action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=BltBindCreateSerializer) @transaction.atomic def blt_bind(self, request): """绑定/解绑定位卡 绑定/解绑定位卡 """ serializer = BltBindCreateSerializer(data=request.data) serializer.is_valid(raise_exception=True) vdata = serializer.validated_data code = vdata['code'] blt = TDevice.objects.filter( code=code, type=TDevice.DEVICE_BLT).first() if blt: if vdata['type'] == BltBind.BLT_BIND and vdata['employee']: if blt.employee: raise ParseError('该定位卡已绑定人员,请先解绑') else: blt.employee = vdata['employee'] blt.obj_cate = 'people' blt.save() vdata['obj_cate'] = 'people' vdata.pop('code') vdata['blt'] = blt BltBind.objects.create(**vdata) elif vdata['type'] == BltBind.BLT_UNBIND: ep_old = blt.employee if blt.employee: blt.employee = None blt.save() vdata['obj_cate'] = 'people' vdata.pop('code') vdata['blt'] = blt vdata['employee'] = ep_old BltBind.objects.create(**vdata) else: raise ParseError('该定位卡在系统中不存在') return Response() @action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=Serializer, logging_methods=[]) def blt(self, request): """定位标签列表 定位标签列表 """ _, res = xxClient.request(**xxapis['blt_list'], json=request.data) macs = [] for i in res['recordList']: macs.append(i['mac']) qs = self.queryset.filter(code__in=macs) qs_data = BltSerializer(instance=qs, many=True).data qs_dict = {} for i in qs_data: qs_dict[i['code']] = i for i in res['recordList']: i['my_info'] = {} if i['mac'] in qs_dict: i['my_info'] = qs_dict[i['mac']] return Response(res) @action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=Serializer, logging_methods=[]) def vchannel(self, request): """ 视频通道列表 视频通道列表 """ request.data.update({ 'unitTypeList': ["1"], 'includeSubOwnerCodeFlag': True }) _, res = dhClient.request(**dhapis['channel_list'], json=request.data) codes = [] if res.get('pageData', None): for i in res['pageData']: codes.append(i['channelCode']) tds_info = TDeviceSerializer( instance=TDevice.objects.filter(code__in=codes), many=True).data tds_dict = {} for i in tds_info: tds_dict[i['code']] = i for i in res['pageData']: i['my_info'] = {} if i['channelCode'] in tds_dict: i['my_info'] = tds_dict[i['channelCode']] return Response(res) @action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=Serializer, logging_methods=[]) def speaker(self, request): """ 喇叭列表 喇叭列表 """ # print(request.data) _, res = spClient.request(**spapis['device_list'], params=request.data) codes = [] for i in res['rows']: codes.append(i['sn']) tds_info = TDeviceSerializer( instance=TDevice.objects.filter(code__in=codes), many=True).data tds_dict = {} for i in tds_info: tds_dict[i['code']] = i for i in res['rows']: i['my_info'] = {} if i['sn'] in tds_dict: i['my_info'] = tds_dict[i['sn']] return Response(res) @action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=Serializer, logging_methods=[]) def dchannel(self, request): """ 闸机通道列表 闸机通道列表 """ request.data.update({ 'unitTypeList': ["7"], 'includeSubOwnerCodeFlag': True }) _, res = dhClient.request(**dhapis['channel_list'], json=request.data) codes = [] if res.get('pageData', None): for i in res['pageData']: codes.append(i['channelCode']) tds_info = TDeviceSerializer( instance=TDevice.objects.filter(code__in=codes), many=True).data tds_dict = {} for i in tds_info: tds_dict[i['code']] = i for i in res['pageData']: i['my_info'] = {} if i['channelCode'] in tds_dict: i['my_info'] = tds_dict[i['channelCode']] return Response(res) @action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=Serializer, logging_methods=[]) def dchannel_auth(self, request): """ 门禁权限 门禁权限 """ _, res = dhClient.request( **dhapis['card_door_authority_list'], json=request.data) codes = [] if res.get('pageData', None): for i in res['pageData']: codes.append(i['cardNumber']) eps_info = EmployeeShortSerializer( instance=Employee.objects.filter(third_info__dh_face_card__in=codes), many=True).data eps_dict = {} for i in eps_info: eps_dict[i['third_info']['dh_face_card']] = i for i in res['pageData']: i['my_info'] = {} if i['cardNumber'] in eps_dict: i['my_info'] = eps_dict[i['cardNumber']] return Response(res) @action(methods=['post'], detail=True, perms_map={'post': 'tdevice.label_location'}, serializer_class=LabelLocationSerializer) def label_location(self, request, pk=None): """ 标注坐标位置 标注坐标位置 """ obj = self.get_object() sr = LabelLocationSerializer(instance=obj, data=request.data) sr.is_valid(raise_exception=True) sr.save() return Response() # serializer = self.get_serializer(data=request.data) # serializer.is_valid(raise_exception=True) # vdata = serializer.validated_data # td = TDevice.objects.filter(code=vdata['code']).first() # if td: # td.location = vdata['location'] # td.type = vdata['type'] # td.area = vdata['area'] # td.name = vdata['name'] # td.update_by = request.user # td.save() # td.areas.clear() # for i in vdata['areas']: # td.areas.add(i) # else: # td = TDevice() # td.type = vdata['type'] # td.code = vdata['code'] # td.location = vdata['location'] # td.area = vdata['area'] # td.name = vdata['name'] # td.create_by = request.user # td.save() # td.areas.clear() # for i in vdata['areas']: # td.areas.add(i) # return Response() @action(methods=['post'], detail=False, perms_map={'post': 'tdevice.bind_area'}, serializer_class=BindAreaSerializer) def bind_area(self, request): """ 批量绑定所在区域 批量绑定所在区域 """ serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) vdata = serializer.validated_data TDevice.objects.filter(id__in=vdata['ids']).update(area=vdata['area']) return Response() # area = Area.objects.get(id=vdata['area']) # for i in vdata['codes']: # td = TDevice.objects.filter(code=i['code']).first() # if td: # td.area = area # td.update_by = request.user # td.save() # else: # td = TDevice() # td.type = TDevice.DEVICE_VCHANNEL # td.code = i['code'] # td.area = area # td.create_by = request.user # td.save() # return Response() class TlogViewSet(ListModelMixin, CustomGenericViewSet): perms_map = {'get': '*'} queryset = Tlog.objects.all() serializer_class = TlogSerializer filterset_fields = ['result', 'id'] class DoorAuthViewSet(ListModelMixin, DestroyModelMixin, CustomGenericViewSet): """ list: 门禁权限 门禁权限 """ perms_map = {'get': '*', 'delete': 'doorauth.delete'} queryset = DoorAuth.objects.all() serializer_class = DoorAuthSerializer filterset_class = DoorAuthFilter select_related_fields = ['dchannel', 'employee'] search_fields = ['employee__name'] ordering = '-create_time' @transaction.atomic def perform_destroy(self, instance): dh_face_card = instance.employee.third_info['dh_face_card'] dh_id = instance.employee.third_info['dh_id'] rdict = {"personIdsString": str(dh_id), "cardNumberString": str(dh_face_card), "channelCode": instance.dchannel.code} dhClient.request(**dhapis['card_door_authority_delete'], json=rdict) instance.delete()