from django.db import models from django.conf import settings from django.db.models.signals import post_save from django.dispatch import receiver from django.utils.translation import gettext_lazy as _ class OnlineExamEvent(models.Model): EVENT_EXIT_FULLSCREEN = 'ExitFullScreen' EVENT_LOSTFOCUS = 'LostFocus' EVENT_IDENTITY_VERIFICATION = 'IdentityVerification' EVENT_GET_PAPER = 'GetPaper' EVENT_SAVE_DRAFT = 'SaveDraft' EVENT_SUBMIT = 'Submit' EVENT_ADMIN_FORCE_SUBMIT = 'AdminForceSubmit' EVENT_ADMIN_WARING_MESSAGE = 'AdminWarningMessage' EVENT_IDENTITY_FAILED = 'IdentityFailed' EVENT_FACE_CHECK_FAILED = 'FaceCheckFailed' EVENT_CHOICES = ( (EVENT_EXIT_FULLSCREEN, _('Exit Full Screen')), (EVENT_LOSTFOCUS, _('Lost Focus')), (EVENT_IDENTITY_VERIFICATION, _('Identity Verification')), (EVENT_GET_PAPER, _('Get Paper')), (EVENT_SAVE_DRAFT, _('Save Draft')), (EVENT_SUBMIT, _('Submit Paper')), (EVENT_ADMIN_FORCE_SUBMIT, _('Force Submit By Admin')), (EVENT_ADMIN_WARING_MESSAGE, _('Send Warning Message By Admin')), (EVENT_IDENTITY_FAILED, _('Examinee Identity Failed')), (EVENT_FACE_CHECK_FAILED, _('Examinee Face Check Failed')), ) user = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING) online_exam = models.ForeignKey( 'university.OnlineExam', on_delete=models.CASCADE) user_online_exam = models.ForeignKey( 'university.UserOnlineExam', on_delete=models.CASCADE) event_type = models.CharField(max_length=64, choices=EVENT_CHOICES) comment = models.CharField(max_length=255) ip = models.CharField(max_length=255, blank=True, null=True) user_agent = models.CharField(max_length=255, blank=True, null=True) created_at = models.DateTimeField(auto_now_add=True) class Meta: db_table = 'online_exam_events' @receiver( post_save, sender='university.OnlineExamEvent', dispatch_uid='_sync_online_exam_event_to_wechat') def _sync_online_exam_event_to_wechat(sender, instance, created, **kwargs): # 将用户的异常操作发送到企业微信 if not created or not instance.online_exam.alert_wechat_webhook: return # 跳过正常操作 if instance.event_type in [ OnlineExamEvent.EVENT_GET_PAPER, OnlineExamEvent.EVENT_SAVE_DRAFT, OnlineExamEvent.EVENT_SUBMIT]: return from university.tasks.online_exam import async_send_alert_to_wechat examinee_admin_url = '{}/admin/dashboard#/online-exam/{}/examinee/{}'.format( settings.BASE_URL, instance.online_exam_id, instance.user_id) msg_content = '### [{} - {} 异常行为]({})\n>\n'.format( instance.online_exam.name, instance.user_online_exam.examinee_name, examinee_admin_url) msg_content += '>**事件类型:**{}\n>\n'.format(instance.event_type) msg_content += '>**事件说明:**{}\n>\n'.format(instance.get_event_type_display()) if instance.comment: msg_content += '>**备注:**{}\n>\n'.format(instance.comment) async_send_alert_to_wechat.delay( instance.online_exam.alert_wechat_webhook, msg_content)