From 5ebd884f18fdf0faf576bbb9fa6f1d68293d8c80 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Tue, 14 Mar 2023 15:04:00 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A6=BB=E7=BA=BF=E5=88=B7=E5=8D=A1=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E8=AE=A2=E9=98=85=E4=B8=8E=E6=8E=A8=E9=80=81=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/hrm/services.py | 241 +++++++++++++++++++++++-------------------- apps/third/views.py | 18 ++++ 2 files changed, 148 insertions(+), 111 deletions(-) diff --git a/apps/hrm/services.py b/apps/hrm/services.py index 20454c1d..0c1a2ccb 100755 --- a/apps/hrm/services.py +++ b/apps/hrm/services.py @@ -10,6 +10,7 @@ from apps.utils.tools import rannum, ranstr from datetime import datetime, timedelta from django.utils import timezone from dateutil import tz +from threading import Thread myLogger = logging.getLogger('log') @@ -205,69 +206,157 @@ class HrmService: @classmethod def swipe(cls, data: dict): """ - 刷卡事件/用于记录考勤 + 实时刷卡事件/用于记录考勤 + 有身份证号的 """ + id_number = data['info']['extend'].get('paperNumber', None) + if id_number: + nodeCode = data['info']['nodeCode'] + swip_time = data['info']['extend']['swingTime'] + e_type = data['info']['extend']['enterOrExit'] + cls.swipe_next(nodeCode, swip_time, e_type, data['info']['extend']) + + @classmethod + def swipe_offline(cls, data:dict): + """离线刷卡推送记录处理 + """ + for i in data['infoArray']: + id_number = i.get('paperNumber', None) + if id_number: + nodeCode = i['acsChannelCode'] + swip_time = i['swingTime'] + e_type = i['enterOrExit'] + Thread(target=cls.swipe_next, args=(nodeCode, swip_time, e_type, i), daemon=True).start() + + @classmethod + def swipe_next(cls, nodeCode: str, id_number: str, swip_time: str, e_type:int, detail:dict): from apps.vm.models import Visit from apps.rpm.models import Rpj - nodeCode = data['info']['nodeCode'] - id_number = data['info']['extend'].get('paperNumber', None) - swip_time = data['info']['extend']['swingTime'] - if id_number: - device = TDevice.objects.filter(code=nodeCode).first() - if device: - tzinfo = tz.gettz('Asia/Shanghai') - s_time_f = datetime.strptime(swip_time, "%Y-%m-%d %H:%M:%S").replace(tzinfo=tzinfo) - first_time = datetime(year=s_time_f.year, month=s_time_f.month, day=s_time_f.day, - hour=0, minute=0, second=0, tzinfo=tzinfo) - end_time = datetime(year=s_time_f.year, month=s_time_f.month, day=s_time_f.day, - hour=23, minute=59, second=59, tzinfo=tzinfo) - if device.is_clock: - # 如果设置为关联考勤 - # myLogger.info(data['info']['extend']) - if data['info']['extend']['enterOrExit'] == 1: - # 如果是进门 - ep = Employee.objects.filter(id_number=id_number, type__in=["employee", "remployee"]).first() - # 如果是内部/相关方员工创建上班打卡记录(更新) - if ep: + device = TDevice.objects.filter(code=nodeCode).first() + if device: + tzinfo = tz.gettz('Asia/Shanghai') + s_time_f = datetime.strptime(swip_time, "%Y-%m-%d %H:%M:%S").replace(tzinfo=tzinfo) + first_time = datetime(year=s_time_f.year, month=s_time_f.month, day=s_time_f.day, + hour=0, minute=0, second=0, tzinfo=tzinfo) + end_time = datetime(year=s_time_f.year, month=s_time_f.month, day=s_time_f.day, + hour=23, minute=59, second=59, tzinfo=tzinfo) + if device.is_clock: + # 如果设置为关联考勤 + # myLogger.info(data['info']['extend']) + if e_type == 1: + # 如果是进门 + ep = Employee.objects.filter(id_number=id_number, type__in=["employee", "remployee"]).first() + # 如果是内部/相关方员工创建上班打卡记录(更新) + if ep: + cr_10 = ClockRecord.objects.filter( + type=10, employee=ep, create_time__gte=first_time, create_time__lte=end_time).first() + if cr_10: + if s_time_f < cr_10.create_time: + cr_10.create_time = s_time_f + cr_10.trigger = 'door' + cr_10.detail = detail + cr_10.save() + else: + cr_10 = ClockRecord() + cr_10.type = 10 + cr_10.employee = ep + cr_10.trigger = 'door' + cr_10.detail = detail + cr_10.create_time = s_time_f + cr_10.save() + ep.is_atwork = True + ep.last_check_time = s_time_f + ep.save() + elif e_type == 2: + # 如果是出门 + ep = Employee.objects.filter(id_number=id_number, type__in=[ + "employee", "remployee"]).first() + # 如果是内部/相关方员工创建下班打卡记录(更新) + if ep: + cr_20 = ClockRecord.objects.filter( + type=20, employee=ep, create_time__gte=first_time, create_time__lte=end_time).first() + if cr_20: + if s_time_f > cr_20.create_time: + cr_20.create_time = s_time_f + cr_20.trigger = 'door' + cr_20.detail = detail + cr_20.save() + else: + cr_20 = ClockRecord() + cr_20.type = 20 + cr_20.employee = ep + cr_20.trigger = 'door' + cr_20.detail = detail + cr_20.create_time = s_time_f + cr_20.save() + ep.is_atwork = False + ep.last_check_time = s_time_f + ep.save() + # 判断是否有异常 + # 找到最近的上班时间 + cr_e = ClockRecord.objects.filter(create_time__lte=cr_20.create_time, type=10, employee=ep).order_by('-create_time').first() + if cr_e: + time_d = cr_20.create_time - cr_e.create_time + if time_d < timedelta(hours=7): + cr_20.exception_type = ClockRecord.E_TYPE_LESS + cr_20.save() + elif time_d > timedelta(hours=14): + cr_20.exception_type = ClockRecord.E_TYPE_MORE + cr_20.save() + elif e_type == 3: + # 如果不确定根据时间来 + card_type = None + time_10_x = datetime(year=s_time_f.year, month=s_time_f.month, + day=s_time_f.day, hour=4, minute=0, second=0, tzinfo=tzinfo) + time_10_y = datetime(year=s_time_f.year, month=s_time_f.month, + day=s_time_f.day, hour=11, minute=0, second=0, tzinfo=tzinfo) + time_20_x = datetime(year=s_time_f.year, month=s_time_f.month, + day=s_time_f.day, hour=16, minute=0, second=0, tzinfo=tzinfo) + time_20_y = datetime(year=s_time_f.year, month=s_time_f.month, + day=s_time_f.day, hour=23, minute=0, second=0, tzinfo=tzinfo) + if time_10_x < s_time_f < time_10_y: + card_type = 10 + elif time_20_x < s_time_f < time_20_y: + card_type = 20 + if card_type: + ep = Employee.objects.filter(id_number=id_number, type__in=[ + "employee", "remployee"]).first() + # 如果是内部/相关方员工创建下班打卡记录(更新) + if ep and card_type == 10: cr_10 = ClockRecord.objects.filter( type=10, employee=ep, create_time__gte=first_time, create_time__lte=end_time).first() if cr_10: if s_time_f < cr_10.create_time: cr_10.create_time = s_time_f - cr_10.trigger = 'door' - cr_10.detail = data['info']['extend'] + cr_10.trigger = 'panel' + cr_10.detail = detail cr_10.save() else: cr_10 = ClockRecord() cr_10.type = 10 cr_10.employee = ep - cr_10.trigger = 'door' - cr_10.detail = data['info']['extend'] + cr_10.trigger = 'panel' + cr_10.detail = detail cr_10.create_time = s_time_f cr_10.save() ep.is_atwork = True ep.last_check_time = s_time_f ep.save() - elif data['info']['extend']['enterOrExit'] == 2: - # 如果是出门 - ep = Employee.objects.filter(id_number=id_number, type__in=[ - "employee", "remployee"]).first() - # 如果是内部/相关方员工创建下班打卡记录(更新) - if ep: + elif ep and card_type == 20: cr_20 = ClockRecord.objects.filter( type=20, employee=ep, create_time__gte=first_time, create_time__lte=end_time).first() if cr_20: if s_time_f > cr_20.create_time: cr_20.create_time = s_time_f - cr_20.trigger = 'door' - cr_20.detail = data['info']['extend'] + cr_20.trigger = 'panel' + cr_20.detail = detail cr_20.save() else: cr_20 = ClockRecord() cr_20.type = 20 cr_20.employee = ep - cr_20.trigger = 'door' - cr_20.detail = data['info']['extend'] + cr_20.trigger = 'panel' + cr_20.detail = detail cr_20.create_time = s_time_f cr_20.save() ep.is_atwork = False @@ -284,81 +373,11 @@ class HrmService: elif time_d > timedelta(hours=14): cr_20.exception_type = ClockRecord.E_TYPE_MORE cr_20.save() - elif data['info']['extend']['enterOrExit'] == 3: - # 如果不确定根据时间来 - card_type = None - time_10_x = datetime(year=s_time_f.year, month=s_time_f.month, - day=s_time_f.day, hour=4, minute=0, second=0, tzinfo=tzinfo) - time_10_y = datetime(year=s_time_f.year, month=s_time_f.month, - day=s_time_f.day, hour=11, minute=0, second=0, tzinfo=tzinfo) - time_20_x = datetime(year=s_time_f.year, month=s_time_f.month, - day=s_time_f.day, hour=16, minute=0, second=0, tzinfo=tzinfo) - time_20_y = datetime(year=s_time_f.year, month=s_time_f.month, - day=s_time_f.day, hour=23, minute=0, second=0, tzinfo=tzinfo) - if time_10_x < s_time_f < time_10_y: - card_type = 10 - elif time_20_x < s_time_f < time_20_y: - card_type = 20 - if card_type: - ep = Employee.objects.filter(id_number=id_number, type__in=[ - "employee", "remployee"]).first() - # 如果是内部/相关方员工创建下班打卡记录(更新) - if ep and card_type == 10: - cr_10 = ClockRecord.objects.filter( - type=10, employee=ep, create_time__gte=first_time, create_time__lte=end_time).first() - if cr_10: - if s_time_f < cr_10.create_time: - cr_10.create_time = s_time_f - cr_10.trigger = 'panel' - cr_10.detail = data['info']['extend'] - cr_10.save() - else: - cr_10 = ClockRecord() - cr_10.type = 10 - cr_10.employee = ep - cr_10.trigger = 'panel' - cr_10.detail = data['info']['extend'] - cr_10.create_time = s_time_f - cr_10.save() - ep.is_atwork = True - ep.last_check_time = s_time_f - ep.save() - elif ep and card_type == 20: - cr_20 = ClockRecord.objects.filter( - type=20, employee=ep, create_time__gte=first_time, create_time__lte=end_time).first() - if cr_20: - if s_time_f > cr_20.create_time: - cr_20.create_time = s_time_f - cr_20.trigger = 'panel' - cr_20.detail = data['info']['extend'] - cr_20.save() - else: - cr_20 = ClockRecord() - cr_20.type = 20 - cr_20.employee = ep - cr_20.trigger = 'panel' - cr_20.detail = data['info']['extend'] - cr_20.create_time = s_time_f - cr_20.save() - ep.is_atwork = False - ep.last_check_time = s_time_f - ep.save() - # 判断是否有异常 - # 找到最近的上班时间 - cr_e = ClockRecord.objects.filter(create_time__lte=cr_20.create_time, type=10, employee=ep).order_by('-create_time').first() - if cr_e: - time_d = cr_20.create_time - cr_e.create_time - if time_d < timedelta(hours=7): - cr_20.exception_type = ClockRecord.E_TYPE_LESS - cr_20.save() - elif time_d > timedelta(hours=14): - cr_20.exception_type = ClockRecord.E_TYPE_MORE - cr_20.save() - # 进行相关方/访客项目更新 - Visit.objects.filter(state=Visit.V_ENTER, visitors__employee__id_number=id_number).update( - state=Visit.V_WORKING) - Rpj.objects.filter(state=Rpj.RPJ_ENTER, remployees__employee__id_number=id_number).update( - state=Rpj.RPJ_WORKING) + # 进行相关方/访客项目更新 + Visit.objects.filter(state=Visit.V_ENTER, visitors__employee__id_number=id_number).update( + state=Visit.V_WORKING) + Rpj.objects.filter(state=Rpj.RPJ_ENTER, remployees__employee__id_number=id_number).update( + state=Rpj.RPJ_WORKING) - # 此处可触发安全帽事件逻辑 \ No newline at end of file + # 此处可触发安全帽事件逻辑 \ No newline at end of file diff --git a/apps/third/views.py b/apps/third/views.py index e32c45db..8171bb13 100755 --- a/apps/third/views.py +++ b/apps/third/views.py @@ -343,6 +343,22 @@ class DhCommonViewSet(CreateModelMixin, CustomGenericViewSet): ] }, ] + }, + { + "monitor": settings.BASE_URL + '/api/third/dahua/c_swip/', + "monitorType": "url", + "events": [ + { + "category": "business", + "subscribeAll": 1, + "domainSubscribe": 2, + "authorities": [ + { + "types": ["cardRecord.offline"] + } + ] + }, + ] } ], "subsystem": { @@ -380,6 +396,8 @@ class DhCommonViewSet(CreateModelMixin, CustomGenericViewSet): subsystem = data.get('subsystem', None) if method == 'alarm.msg' and subsystem == 'evo-accesscontrol': HrmService.swipe(data=data) + elif method == 'cardRecord.offline' and subsystem == 'evo-accesscontrol': + HrmService.swipe_offline(data=data) return Response() @action(methods=['post'], detail=False,