247 lines
10 KiB
Python
247 lines
10 KiB
Python
|
|
from threading import Thread
|
|
|
|
from django.db import transaction
|
|
from django.db.models import Count, F
|
|
from django.utils import timezone
|
|
from rest_framework import serializers
|
|
from rest_framework.decorators import action
|
|
from rest_framework.exceptions import PermissionDenied
|
|
from rest_framework.mixins import (CreateModelMixin, DestroyModelMixin,
|
|
ListModelMixin, RetrieveModelMixin,
|
|
UpdateModelMixin)
|
|
from rest_framework.response import Response
|
|
from rest_framework.exceptions import ParseError
|
|
from apps.ecm.filters import EventFilterSet
|
|
from apps.ecm.models import (AlgoChannel, Event, EventCate, Eventdo,
|
|
NotifySetting, Remind)
|
|
from apps.ecm.serializers import (AlgoChannelCreateSerializer,
|
|
AlgoChannelCreatesSerializer,
|
|
AlgoChannelSerializer, EventAggSerializer,
|
|
EventCateCreateUpdateSerializer,
|
|
EventCateListSerializer, EventDetailSerializer,
|
|
EventHandleSerializer, EventSerializer, EventSimpleSerializer,
|
|
NotifySettingsSerializer, RemindSerializer)
|
|
from apps.ecm.service import update_remind_read
|
|
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
|
|
from apps.utils.export import export_excel_img
|
|
from apps.ecm.tasks import monitor_check
|
|
from apps.utils.mixins import BulkDestroyModelMixin
|
|
|
|
obj_cate_dict = {'people': '人员', 'opl': '作业', 'other': '其他'}
|
|
mark_dict = {10: '正常', 20: '误报'}
|
|
|
|
# Create your views here.
|
|
|
|
|
|
class EventCateViewSet(CreateModelMixin, UpdateModelMixin, ListModelMixin, CustomGenericViewSet):
|
|
perms_map = {'get': '*', 'put': 'event_cate.update', 'post': 'event_cate.create'}
|
|
queryset = EventCate.objects.all()
|
|
list_serializer_class = EventCateListSerializer
|
|
create_serializer_class = EventCateCreateUpdateSerializer
|
|
update_serializer_class = EventCateCreateUpdateSerializer
|
|
serializer_class = EventCateListSerializer
|
|
filterset_fields = ['self_algo', 'trigger']
|
|
ordering = ['priority', 'create_time']
|
|
|
|
|
|
class AlgoChannelViewSet(CreateModelMixin, DestroyModelMixin, ListModelMixin, CustomGenericViewSet):
|
|
perms_map = {'get': '*', 'post': 'event_cate.update', 'delete': 'event_cate.update'}
|
|
queryset = AlgoChannel.objects.all()
|
|
create_serializer_class = AlgoChannelCreateSerializer
|
|
serializer_class = AlgoChannelSerializer
|
|
filterset_fields = ['algo']
|
|
|
|
@transaction.atomic
|
|
@action(methods=['post'], detail=False, perms_map={'post': 'event_cate.update'},
|
|
serializer_class=AlgoChannelCreatesSerializer)
|
|
def creates(self, request, pk=None):
|
|
"""批量添加摄像头
|
|
|
|
批量添加摄像头
|
|
"""
|
|
serializer = AlgoChannelCreatesSerializer(data=request.data)
|
|
serializer.is_valid(raise_exception=True)
|
|
vdata = serializer.validated_data
|
|
for i in vdata['vchannels']:
|
|
AlgoChannel.objects.get_or_create(algo=vdata['algo'], vchannel=i,
|
|
defaults={
|
|
"algo": vdata['algo'],
|
|
"vchannel": i
|
|
})
|
|
return Response()
|
|
|
|
def perform_create(self, serializer):
|
|
ins = serializer.save()
|
|
if ins.always_on:
|
|
monitor_check([ins.vchannel.id])
|
|
|
|
def perform_destroy(self, instance):
|
|
vid = instance.vchannel.id
|
|
instance.delete()
|
|
monitor_check([vid])
|
|
|
|
|
|
|
|
class NotifySettingViewSet(CustomModelViewSet):
|
|
queryset = NotifySetting.objects.all()
|
|
serializer_class = NotifySettingsSerializer
|
|
filterset_fields = ['event_cate', 'obj_cate', 'post', 'user']
|
|
ordering = ['sort', 'create_time']
|
|
|
|
|
|
class EventViewSet(ListModelMixin, RetrieveModelMixin, BulkDestroyModelMixin, CustomGenericViewSet):
|
|
perms_map = {'get': '*', 'delete': 'event.delete'}
|
|
queryset = Event.objects.all()
|
|
serializer_class = EventSerializer
|
|
retrieve_serializer_class = EventDetailSerializer
|
|
select_related_fields = ['area', 'employee', 'handle_user', 'vchannel', 'opl']
|
|
prefetch_related_fields = ['cates']
|
|
filterset_class = EventFilterSet
|
|
|
|
@transaction.atomic
|
|
@action(methods=['post'], detail=True, perms_map={'post': 'event.handle'},
|
|
serializer_class=EventHandleSerializer)
|
|
def handle(self, request, pk=None):
|
|
"""处理事件
|
|
|
|
处理事件
|
|
"""
|
|
obj = self.get_object()
|
|
# 判断当前用户有无处理权限(废弃, 通过控权实现即可)
|
|
# if (not Remind.objects.filter(event=obj, recipient=request.user, can_handle=True).exists()) and (
|
|
# not request.user.is_superuser):
|
|
# raise PermissionDenied('您无权处理该事件')
|
|
data = request.data
|
|
sr = EventHandleSerializer(instance=obj, data=data)
|
|
sr.is_valid(raise_exception=True)
|
|
sr.save(handle_user=request.user, handle_time=timezone.now())
|
|
Thread(target=update_remind_read, args=(obj, request.user), daemon=True).start()
|
|
return Response()
|
|
|
|
def retrieve(self, request, *args, **kwargs):
|
|
obj = self.get_object()
|
|
Thread(target=update_remind_read, args=(obj, request.user), daemon=True).start()
|
|
return super().retrieve(request, *args, **kwargs)
|
|
|
|
@transaction.atomic
|
|
@action(methods=['post'], detail=False, perms_map={'post': '*'},
|
|
serializer_class=EventAggSerializer, logging_methods=[])
|
|
def cate_agg(self, request, pk=None):
|
|
"""按事件分类聚合
|
|
|
|
按事件分类聚合
|
|
"""
|
|
slr = EventAggSerializer(data=request.data)
|
|
slr.is_valid(raise_exception=True)
|
|
vdata = slr.validated_data
|
|
ret = {}
|
|
queryset = Eventdo.objects.all()
|
|
if vdata.get('start_create', None):
|
|
queryset = queryset.filter(event__create_time__gte=vdata['start_create'])
|
|
if vdata.get('end_create', None):
|
|
queryset = queryset.filter(event__create_time__lte=vdata['end_create'])
|
|
if vdata.get('is_handled', None):
|
|
if vdata['is_handled']:
|
|
queryset = queryset.exclude(event__handle_user=None)
|
|
else:
|
|
queryset = queryset.filter(event__handle_user=None)
|
|
ret['total_count'] = queryset.count()
|
|
if vdata.get('completed', True):
|
|
ret['details'] = list(EventCate.objects.order_by('priority', 'create_time').annotate(cate=F('id'),
|
|
cate__name=F('name'), cate__trigger=F('trigger')).values('cate', 'cate__name'))
|
|
for i in ret['details']:
|
|
i['count'] = queryset.filter(cate__id=i['cate']).count()
|
|
else:
|
|
ret['details'] = list(queryset.order_by('cate__priority', 'cate__create_time').values(
|
|
'cate', 'cate__name', 'cate__trigger').annotate(count=Count('cate')))
|
|
return Response(ret)
|
|
|
|
@action(methods=['get'], detail=False, perms_map={'get': '*'},
|
|
serializer_class=serializers.Serializer)
|
|
def export_excel(self, request, pk=None):
|
|
"""导出excel
|
|
导出excel
|
|
"""
|
|
field_data = [
|
|
{"name": "事件种类", "type": "str"},
|
|
{"name": "发生区域", "type": "str"},
|
|
{"name": "事件类型", "type": "str"},
|
|
{"name": "当事人", "type": "str"},
|
|
{"name": "所属作业", "type": "str"},
|
|
{"name": "发生时间", "type": "str"},
|
|
{"name": "处理人", "type": "str"},
|
|
{"name": "事件标记", "type": "str"},
|
|
{"name": "抓拍图", "type": "img"},
|
|
{"name": "人脸图", "type": "img"},
|
|
]
|
|
queryset = self.filter_queryset(self.get_queryset())
|
|
if queryset.count() > 15000:
|
|
raise ParseError('数量超过15000,请筛选后导出')
|
|
odata = EventSerializer(queryset, many=True).data
|
|
# 处理数据
|
|
data = []
|
|
|
|
for i in odata:
|
|
cates_str = ''
|
|
for m in i['cates_']:
|
|
cates_str = cates_str + m['name'] + '/'
|
|
data.append(
|
|
[
|
|
cates_str,
|
|
i.get('area_name', None),
|
|
obj_cate_dict[i['obj_cate']],
|
|
i.get('employee_name', None),
|
|
i.get('operation_name', None),
|
|
i['create_time'],
|
|
i.get('handle_user_name', None),
|
|
mark_dict.get(i['mark'], '正常'),
|
|
i['global_img_compressed'],
|
|
i['face_img']
|
|
]
|
|
)
|
|
return Response({'path': export_excel_img(field_data, data, '事件记录')})
|
|
|
|
|
|
class RemindViewSet(ListModelMixin, CustomGenericViewSet):
|
|
perms_map = {'get': '*'}
|
|
queryset = Remind.objects.all()
|
|
serializer_class = RemindSerializer
|
|
select_related_fields = ['recipient', 'event']
|
|
prefetch_related_fields = ['event__cates']
|
|
filterset_fields = ['event', 'event__cates', 'is_read']
|
|
|
|
@action(methods=['get'], detail=False, perms_map={'get': '*'})
|
|
def my(self, request, *args, **kwargs):
|
|
"""推送给我的
|
|
|
|
推送给我的
|
|
"""
|
|
user = self.request.user
|
|
queryset = self.filter_queryset(self.get_queryset().filter(recipient=user))
|
|
|
|
page = self.paginate_queryset(queryset)
|
|
if page is not None:
|
|
serializer = self.get_serializer(page, many=True)
|
|
return self.get_paginated_response(serializer.data)
|
|
|
|
serializer = self.get_serializer(queryset, many=True)
|
|
return Response(serializer.data)
|
|
|
|
|
|
# class MyRemindViewSet(ListModelMixin, CustomGenericViewSet):
|
|
# perms_map = {'get': '*'}
|
|
# serializer_class = RemindSerializer
|
|
# select_related_fields = ['recipient', 'event']
|
|
# prefetch_related_fields = ['event__cates']
|
|
|
|
# def get_queryset(self):
|
|
# return Remind.objects.filter(recipient=self.request.user)
|
|
|
|
# @action(methods=['post'], detail=True, perms_map={'post': '*'})
|
|
# def label_read(self, request, *args, **kwargs):
|
|
# """标记已读
|
|
|
|
# 标记已读
|
|
# """
|