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

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 datetime import datetime, timedelta
from django.utils import timezone from django.utils import timezone
from dateutil import tz from dateutil import tz
from threading import Thread
myLogger = logging.getLogger('log') myLogger = logging.getLogger('log')
@ -205,69 +206,157 @@ class HrmService:
@classmethod @classmethod
def swipe(cls, data: dict): 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.vm.models import Visit
from apps.rpm.models import Rpj from apps.rpm.models import Rpj
nodeCode = data['info']['nodeCode'] device = TDevice.objects.filter(code=nodeCode).first()
id_number = data['info']['extend'].get('paperNumber', None) if device:
swip_time = data['info']['extend']['swingTime'] tzinfo = tz.gettz('Asia/Shanghai')
if id_number: s_time_f = datetime.strptime(swip_time, "%Y-%m-%d %H:%M:%S").replace(tzinfo=tzinfo)
device = TDevice.objects.filter(code=nodeCode).first() first_time = datetime(year=s_time_f.year, month=s_time_f.month, day=s_time_f.day,
if device: hour=0, minute=0, second=0, tzinfo=tzinfo)
tzinfo = tz.gettz('Asia/Shanghai') end_time = datetime(year=s_time_f.year, month=s_time_f.month, day=s_time_f.day,
s_time_f = datetime.strptime(swip_time, "%Y-%m-%d %H:%M:%S").replace(tzinfo=tzinfo) hour=23, minute=59, second=59, tzinfo=tzinfo)
first_time = datetime(year=s_time_f.year, month=s_time_f.month, day=s_time_f.day, if device.is_clock:
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, # myLogger.info(data['info']['extend'])
hour=23, minute=59, second=59, tzinfo=tzinfo) if e_type == 1:
if device.is_clock: # 如果是进门
# 如果设置为关联考勤 ep = Employee.objects.filter(id_number=id_number, type__in=["employee", "remployee"]).first()
# myLogger.info(data['info']['extend']) # 如果是内部/相关方员工创建上班打卡记录(更新)
if data['info']['extend']['enterOrExit'] == 1: if ep:
# 如果是进门 cr_10 = ClockRecord.objects.filter(
ep = Employee.objects.filter(id_number=id_number, type__in=["employee", "remployee"]).first() type=10, employee=ep, create_time__gte=first_time, create_time__lte=end_time).first()
# 如果是内部/相关方员工创建上班打卡记录(更新) if cr_10:
if ep: 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( cr_10 = ClockRecord.objects.filter(
type=10, employee=ep, create_time__gte=first_time, create_time__lte=end_time).first() type=10, employee=ep, create_time__gte=first_time, create_time__lte=end_time).first()
if cr_10: if cr_10:
if s_time_f < cr_10.create_time: if s_time_f < cr_10.create_time:
cr_10.create_time = s_time_f cr_10.create_time = s_time_f
cr_10.trigger = 'door' cr_10.trigger = 'panel'
cr_10.detail = data['info']['extend'] cr_10.detail = detail
cr_10.save() cr_10.save()
else: else:
cr_10 = ClockRecord() cr_10 = ClockRecord()
cr_10.type = 10 cr_10.type = 10
cr_10.employee = ep cr_10.employee = ep
cr_10.trigger = 'door' cr_10.trigger = 'panel'
cr_10.detail = data['info']['extend'] cr_10.detail = detail
cr_10.create_time = s_time_f cr_10.create_time = s_time_f
cr_10.save() cr_10.save()
ep.is_atwork = True ep.is_atwork = True
ep.last_check_time = s_time_f ep.last_check_time = s_time_f
ep.save() ep.save()
elif data['info']['extend']['enterOrExit'] == 2: elif ep and card_type == 20:
# 如果是出门
ep = Employee.objects.filter(id_number=id_number, type__in=[
"employee", "remployee"]).first()
# 如果是内部/相关方员工创建下班打卡记录(更新)
if ep:
cr_20 = ClockRecord.objects.filter( cr_20 = ClockRecord.objects.filter(
type=20, employee=ep, create_time__gte=first_time, create_time__lte=end_time).first() type=20, employee=ep, create_time__gte=first_time, create_time__lte=end_time).first()
if cr_20: if cr_20:
if s_time_f > cr_20.create_time: if s_time_f > cr_20.create_time:
cr_20.create_time = s_time_f cr_20.create_time = s_time_f
cr_20.trigger = 'door' cr_20.trigger = 'panel'
cr_20.detail = data['info']['extend'] cr_20.detail = detail
cr_20.save() cr_20.save()
else: else:
cr_20 = ClockRecord() cr_20 = ClockRecord()
cr_20.type = 20 cr_20.type = 20
cr_20.employee = ep cr_20.employee = ep
cr_20.trigger = 'door' cr_20.trigger = 'panel'
cr_20.detail = data['info']['extend'] cr_20.detail = detail
cr_20.create_time = s_time_f cr_20.create_time = s_time_f
cr_20.save() cr_20.save()
ep.is_atwork = False ep.is_atwork = False
@ -284,81 +373,11 @@ class HrmService:
elif time_d > timedelta(hours=14): elif time_d > timedelta(hours=14):
cr_20.exception_type = ClockRecord.E_TYPE_MORE cr_20.exception_type = ClockRecord.E_TYPE_MORE
cr_20.save() 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( Visit.objects.filter(state=Visit.V_ENTER, visitors__employee__id_number=id_number).update(
state=Visit.V_WORKING) state=Visit.V_WORKING)
Rpj.objects.filter(state=Rpj.RPJ_ENTER, remployees__employee__id_number=id_number).update( Rpj.objects.filter(state=Rpj.RPJ_ENTER, remployees__employee__id_number=id_number).update(
state=Rpj.RPJ_WORKING) 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": { "subsystem": {
@ -380,6 +396,8 @@ class DhCommonViewSet(CreateModelMixin, CustomGenericViewSet):
subsystem = data.get('subsystem', None) subsystem = data.get('subsystem', None)
if method == 'alarm.msg' and subsystem == 'evo-accesscontrol': if method == 'alarm.msg' and subsystem == 'evo-accesscontrol':
HrmService.swipe(data=data) HrmService.swipe(data=data)
elif method == 'cardRecord.offline' and subsystem == 'evo-accesscontrol':
HrmService.swipe_offline(data=data)
return Response() return Response()
@action(methods=['post'], detail=False, @action(methods=['post'], detail=False,