离线刷卡记录订阅与推送处理

This commit is contained in:
caoqianming 2023-03-14 15:04:00 +08:00
parent 15111a7a9a
commit 5ebd884f18
2 changed files with 148 additions and 111 deletions

View File

@ -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)
# 此处可触发安全帽事件逻辑
# 此处可触发安全帽事件逻辑

View File

@ -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,