diff --git a/apps/am/serializers.py b/apps/am/serializers.py index 7c6a28b5..3d99e695 100644 --- a/apps/am/serializers.py +++ b/apps/am/serializers.py @@ -26,6 +26,9 @@ class AreaCreateUpdateSerializer(CustomModelSerializer): fields = ['name', 'level', 'number', 'visitor_yes', 'remployee_yes', 'employee_yes', 'belong_dept', 'count_people_min', 'count_people_max', 'count_people', 'cate', 'stay_minute_min', 'stay_minute_max', 'manager'] + extra_kwargs = { + 'belong_dept': {'required': True}, + } class AccessCreateSerializer(CustomModelSerializer): diff --git a/apps/ecm/models.py b/apps/ecm/models.py index 8672be8b..0331c96f 100644 --- a/apps/ecm/models.py +++ b/apps/ecm/models.py @@ -118,10 +118,6 @@ class Remind(BaseModel): on_delete=models.CASCADE) notify_setting = models.ForeignKey(NotifySetting, verbose_name='通过哪个配置', on_delete=models.SET_NULL, null=True, blank=True) - post = models.ForeignKey(Post, verbose_name='岗位', - on_delete=models.SET_NULL, null=True, blank=True) - dept = models.ForeignKey(Dept, verbose_name='部门', - on_delete=models.SET_NULL, null=True, blank=True) msg = models.TextField('推送文本', null=True, blank=True) is_read = models.BooleanField('站内信已读', default=False) can_handle = models.BooleanField('是否可处理', default=False) diff --git a/apps/ecm/serializers.py b/apps/ecm/serializers.py index 75405a96..39239ff1 100644 --- a/apps/ecm/serializers.py +++ b/apps/ecm/serializers.py @@ -83,13 +83,22 @@ class EventSerializer(serializers.ModelSerializer): fields = '__all__' +class EventSimpleSerializer(serializers.ModelSerializer): + cates_ = EventCateSimpleSerializer(source='cates', read_only=True, many=True) + + class Meta: + model = Event + fields = ['id', 'cates_', 'voice_msg', 'create_time'] + + class EventHandleSerializer(CustomModelSerializer): class Meta: model = Event - fields = ['handle_desc'] + fields = ['handle_desc', 'mark'] class RemindSerializer(CustomModelSerializer): + event_ = EventSimpleSerializer(source='event', read_only=True) recipient_ = UserSimpleSerializer(source='recipient', read_only=True) class Meta: diff --git a/apps/ecm/service.py b/apps/ecm/service.py index 81cabbe8..faa7865d 100644 --- a/apps/ecm/service.py +++ b/apps/ecm/service.py @@ -5,13 +5,13 @@ from apps.utils.sms import send_sms import requests from apps.am.models import Access, Area from apps.am.tasks import cache_areas_info -from apps.ecm.models import AlgoChannel, Event, EventCate, Eventdo +from apps.ecm.models import AlgoChannel, Event, EventCate, Eventdo, NotifySetting, Remind from apps.hrm.models import Employee from apps.system.models import User from apps.third.clients import xxClient from apps.third.models import TDevice from apps.third.tapis import xxapis -from apps.utils.queryset import get_child_queryset2 +from apps.utils.queryset import get_child_queryset2, get_parent_queryset from django.core.cache import cache import time import shapely.geometry @@ -21,6 +21,8 @@ from django.conf import settings import os from apps.utils.speech import generate_voice from threading import Thread + +from apps.vm.models import Visit requests.packages.urllib3.disable_warnings() @@ -76,8 +78,37 @@ def algo_handle(codes: list, data: dict): return ['helmet'] +def notify_event(event: Event): + """事件后续处理: + + Args: + event (Event): _description_ + """ + # 生成通知文本 + voice_msg = '' + ep = event.employee + if ep: + ep_name = ep.name + ep_type = '员工' + if ep.type == 'rempoyee': + ep_type = '相关方人员' + elif ep.type == 'visitor': + ep_type = '访客' + voice_msg = '位于{}的{}{},'.format(event.area.name, ep_type, ep_name) + else: + voice_msg = '位于{}的未知人员,'.format(event.area.name) + for i in event.cates.all(): + voice_msg = voice_msg + i.name + ',' + event.voice_msg = voice_msg + ',请及时处理' + event.save() + # 喇叭播放 + Thread(target=save_voice_and_speak, args=(event,), daemon=True).start() + # 创建提醒 + Thread(target=create_remind, args=(event,), daemon=True).start() + + def save_voice_and_speak(event: Event): - """生成并保存语音地址并喇叭播放 + """生成语音同时喇叭播放 Args: event (Event): _description_ @@ -99,11 +130,79 @@ def save_voice_and_speak(event: Event): def create_remind(event: Event): """ - 创建事件提醒并发送短信 + 创建事件提醒并发送短信/微信 """ - if event.employee and event.employee.phone: - t_sms = Thread(target=send_sms, args=(event.employee.phone, '1001', {'code': '5678'}), daemon=True) - t_sms.start() + # 向当事人本人发送通知 + # if event.employee and event.employee.phone: + # t_sms = Thread(target=send_sms, args=(event.employee.phone, '1001', {'code': '5678'}), daemon=True) + # t_sms.start() + # 查找所有提醒配置 + n_s = NotifySetting.objects.filter(event_cate__in=event.cates.all()).order_by('sort') + area_level = event.area.level + for i in n_s: + if i.user and area_level >= i.filter_area_level: + Remind.objects.get_or_create(event=event, recipient=i.user, + defaults={ + 'event': event, + 'recipient': i.user, + 'notify_setting': i, + 'can_handle': i.can_handle, + }) + elif i.post and area_level >= i.filter_area_level: + qs = User.objects.filter(posts=i.post) + if i.filter_recipient == 20: # 当事人所在部门以上 + if event.employee and event.employee.user: + qs = qs.filter(depts__in=get_parent_queryset(event.employee.user.belong_dept)) + elif i.filter_recipient == 40: # 属地部门以上 + if event.area.belong_dept: + qs = qs.filter(depts__in=get_parent_queryset(event.area.belong_dept)) + for m in qs: + Remind.objects.get_or_create(event=event, recipient=m, + defaults={ + 'event': event, + 'recipient': m, + 'notify_setting': i, + 'can_handle': i.can_handle, + }) + elif i.variable and area_level >= i.filter_area_level: + if i.variable == 'self': + if event.employee and event.employee.user: + Remind.objects.get_or_create(event=event, recipient=event.employee.user, + defaults={ + 'event': event, + 'recipient': event.employee.user, + 'notify_setting': i, + 'can_handle': i.can_handle, + }) + elif i.variable == 'area_manager': + if event.area.manager: + Remind.objects.get_or_create(event=event, recipient=event.area.manager, + defaults={ + 'event': event, + 'recipient': event.area.manager, + 'notify_setting': i, + 'can_handle': i.can_handle, + }) + elif i.variable == 'visit_receptionist': + if event.employee and event.employee.type == 'visitor': # 确定是访客 + visit = Visit.objects.filter(visitors__employee=event.employee, state=Visit.V_WORKING).first() + if visit: + Remind.objects.get_or_create(event=event, recipient=visit.receptionist, + defaults={ + 'event': event, + 'recipient': visit.receptionist, + 'notify_setting': i, + 'can_handle': i.can_handle, + }) + # 开始发送通知 + for i in Remind.objects.filter(event=event): + if i.notify_setting.sms_enable: + if i.user.employee.phone: + Thread(target=send_sms, args=(i.user.employee.phone, '1001', {'code': '5678'}), daemon=True).start() + if i.notify_setting.wechat_enable: + pass + event.is_pushed = True + event.save() def dispatch_dahua_event(data: dict): @@ -137,20 +236,6 @@ def dispatch_dahua_event(data: dict): event.area = area event.obj_cate = obj_cate event.vchannel = vchannel - voice_msg = '' - if ep: - ep_name = ep.name - ep_type = '员工' - if ep.type == 'rempoyee': - ep_type = '相关方人员' - elif ep.type == 'visitor': - ep_type = '访客' - voice_msg = '位于{}的{}{},'.format(area.name, ep_type, ep_name) - else: - voice_msg = '位于{}的未知人员,'.format(area.name) - for i in ecs: - voice_msg = voice_msg + i.name + ',' - event.voice_msg = voice_msg + ',请及时处理' event.employee = ep event.save() for i in ecs: @@ -159,10 +244,7 @@ def dispatch_dahua_event(data: dict): 'event': event }) if event: - t_v = Thread(target=save_voice_and_speak, args=(event,), daemon=True) - t_v.start() - t_r = Thread(target=create_remind, args=(event,), daemon=True) - t_r.start() + notify_event(event) def dispatch_xunxi_event(data: dict): diff --git a/apps/ecm/views.py b/apps/ecm/views.py index da5ed9cc..1927a13b 100644 --- a/apps/ecm/views.py +++ b/apps/ecm/views.py @@ -71,6 +71,7 @@ class EventViewSet(ListModelMixin, RetrieveModelMixin, CustomGenericViewSet): """ obj = self.get_object() data = request.data + obj.mark = data.get('mark') obj.handle_desc = data.get('handle_desc', '') obj.handle_user = request.user obj.handle_time = timezone.now() @@ -82,6 +83,8 @@ class RemindViewSet(ListModelMixin, CustomGenericViewSet): perms_map = {'get': 'envent:view'} queryset = Remind.objects.all() serializer_class = RemindSerializer + select_related_fields = ['recipient', 'event'] + prefetch_related_fields = ['event__cates'] @action(methods=['get'], detail=False, perms_map={'get': '*'}) def my(self, request, *args, **kwargs): diff --git a/apps/vm/models.py b/apps/vm/models.py index 0057c317..023c91a2 100644 --- a/apps/vm/models.py +++ b/apps/vm/models.py @@ -41,6 +41,7 @@ class Visit(CommonBModel): leave_time = models.DateTimeField('离开时间') count_people = models.PositiveSmallIntegerField('来访人数', null=True, blank=True) receptionist = models.ForeignKey(User, verbose_name='接待人', on_delete=models.CASCADE) + visitors = models.ManyToManyField('vm.visitor', through='vm.vpeople', related_name='v_visitors') # create_by 创建人