门禁和定位在线离线打卡记录
This commit is contained in:
parent
9433459f24
commit
811f96fe83
|
@ -11,19 +11,19 @@ def cache_areas_info():
|
||||||
"""
|
"""
|
||||||
缓存区域信息
|
缓存区域信息
|
||||||
"""
|
"""
|
||||||
area_fix_list = []
|
area_list = []
|
||||||
for i in Area.objects.filter(type=Area.AREA_TYPE_FIX).exclude(third_info__xx_rail=None):
|
for i in Area.objects.filter(is_hidden=False).exclude(third_info__xx_rail=None).order_by('number'):
|
||||||
points = []
|
points = []
|
||||||
for item in i.third_info['xx_rail']['detail']['polygon']['points']:
|
for item in i.third_info['xx_rail']['detail']['polygon']['points']:
|
||||||
points.append((item['x'], item['y']))
|
points.append((item['x'], item['y']))
|
||||||
|
|
||||||
area_dict = {
|
area_dict = {
|
||||||
'id': i.id,
|
'id': i.id,
|
||||||
|
'type': i.type,
|
||||||
'floor_no': i.third_info['xx_rail']['detail']['floorNo'],
|
'floor_no': i.third_info['xx_rail']['detail']['floorNo'],
|
||||||
'polygon': Polygon(points),
|
'polygon': Polygon(points),
|
||||||
'stay_minute_min': i.stay_minute_min,
|
'stay_minute_min': i.stay_minute_min,
|
||||||
'stay_minute_max': i.stay_minute_max
|
'stay_minute_max': i.stay_minute_max
|
||||||
}
|
}
|
||||||
area_fix_list.append(area_dict)
|
area_list.append(area_dict)
|
||||||
cache.set('area_fix_list', area_fix_list, timeout=None)
|
cache.set('area_list', area_list, timeout=None)
|
||||||
return area_fix_list
|
return area_list
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from apps.am.models import Access, Area
|
from apps.am.models import Access, Area
|
||||||
from apps.am.serializers import AccessCreateSerializer, AccessSerializer, AreaCreateUpdateSerializer, AreaSerializer
|
from apps.am.serializers import AccessCreateSerializer, AccessSerializer, AreaCreateUpdateSerializer, AreaSerializer
|
||||||
|
from apps.am.tasks import cache_areas_info
|
||||||
from apps.utils.viewsets import CustomModelViewSet, CustomGenericViewSet
|
from apps.utils.viewsets import CustomModelViewSet, CustomGenericViewSet
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
|
@ -12,7 +13,7 @@ from rest_framework.mixins import ListModelMixin, CreateModelMixin, DestroyModel
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
class AreaViewSet(CustomModelViewSet):
|
class AreaViewSet(CustomModelViewSet):
|
||||||
queryset = Area.objects.all()
|
queryset = Area.objects.all().order_by('number')
|
||||||
create_serializer_class = AreaCreateUpdateSerializer
|
create_serializer_class = AreaCreateUpdateSerializer
|
||||||
update_serializer_class = AreaCreateUpdateSerializer
|
update_serializer_class = AreaCreateUpdateSerializer
|
||||||
serializer_class = AreaSerializer
|
serializer_class = AreaSerializer
|
||||||
|
@ -40,6 +41,7 @@ class AreaViewSet(CustomModelViewSet):
|
||||||
third_info['xx_rail'] = rail_info
|
third_info['xx_rail'] = rail_info
|
||||||
obj.third_info = third_info
|
obj.third_info = third_info
|
||||||
obj.save()
|
obj.save()
|
||||||
|
cache_areas_info.delay()
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
# Generated by Django 3.2.12 on 2022-08-10 07:12
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('am', '0004_auto_20220713_1408'),
|
||||||
|
('ecm', '0012_alter_eventdo_cate'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='event',
|
||||||
|
name='area',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='am.area', verbose_name='发生区域'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='eventcate',
|
||||||
|
name='code',
|
||||||
|
field=models.CharField(max_length=20, unique=True, verbose_name='标识'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -15,7 +15,7 @@ class EventCate(CommonAModel):
|
||||||
(10, '监控'),
|
(10, '监控'),
|
||||||
(20, '定位')
|
(20, '定位')
|
||||||
)
|
)
|
||||||
code = models.CharField('标识', max_length=10, unique=True)
|
code = models.CharField('标识', max_length=20, unique=True)
|
||||||
name = models.CharField('名称', max_length=20, unique=True)
|
name = models.CharField('名称', max_length=20, unique=True)
|
||||||
priority = models.PositiveSmallIntegerField('优先级', default=1, help_text='1-99')
|
priority = models.PositiveSmallIntegerField('优先级', default=1, help_text='1-99')
|
||||||
trigger = models.PositiveSmallIntegerField('触发方式', default=10, choices=EVENT_TRIGGER_CHOICES)
|
trigger = models.PositiveSmallIntegerField('触发方式', default=10, choices=EVENT_TRIGGER_CHOICES)
|
||||||
|
@ -80,7 +80,7 @@ class Event(CommonBModel):
|
||||||
cates = models.ManyToManyField(EventCate, verbose_name='关联事件种类', through='ecm.eventdo')
|
cates = models.ManyToManyField(EventCate, verbose_name='关联事件种类', through='ecm.eventdo')
|
||||||
face_img = models.CharField('人脸照', max_length=1000, null=True, blank=True)
|
face_img = models.CharField('人脸照', max_length=1000, null=True, blank=True)
|
||||||
global_img = models.CharField('全景照', max_length=1000, null=True, blank=True)
|
global_img = models.CharField('全景照', max_length=1000, null=True, blank=True)
|
||||||
area = models.ForeignKey(Area, verbose_name='发生区域', on_delete=models.CASCADE)
|
area = models.ForeignKey(Area, verbose_name='发生区域', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
vchannel = models.ForeignKey(TDevice, verbose_name='抓拍设备', on_delete=models.CASCADE, null=True, blank=True)
|
vchannel = models.ForeignKey(TDevice, verbose_name='抓拍设备', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
location = models.JSONField('事件点位坐标', default=dict, null=False, blank=True)
|
location = models.JSONField('事件点位坐标', default=dict, null=False, blank=True)
|
||||||
obj_cate = models.CharField('发生对象', max_length=20, help_text='people(人员)/...')
|
obj_cate = models.CharField('发生对象', max_length=20, help_text='people(人员)/...')
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
|
|
||||||
|
from apps.opm.models import Operation, Opl, OplWorker
|
||||||
from apps.utils.sms import send_sms
|
from apps.utils.sms import send_sms
|
||||||
import requests
|
import requests
|
||||||
from apps.am.models import Access, Area
|
from apps.am.models import Access, Area
|
||||||
from apps.am.tasks import cache_areas_info
|
from apps.am.tasks import cache_areas_info
|
||||||
from apps.ecm.models import AlgoChannel, Event, EventCate, Eventdo, NotifySetting, Remind
|
from apps.ecm.models import AlgoChannel, Event, EventCate, Eventdo, NotifySetting, Remind
|
||||||
from apps.hrm.models import Employee
|
from apps.hrm.models import ClockRecord, Employee
|
||||||
from apps.system.models import User
|
from apps.system.models import User
|
||||||
from apps.third.models import TDevice
|
from apps.third.models import TDevice
|
||||||
from apps.utils.queryset import get_child_queryset2, get_parent_queryset
|
from apps.utils.queryset import get_child_queryset2, get_parent_queryset
|
||||||
|
@ -58,6 +59,8 @@ def get_ep_default():
|
||||||
"""
|
"""
|
||||||
return {
|
return {
|
||||||
'area_fix_id': None, # 当前所在固定区域ID
|
'area_fix_id': None, # 当前所在固定区域ID
|
||||||
|
'area_temp_id': None, # 当前所在临时区域ID
|
||||||
|
'xx_detail': {}, # 寻息定位的详细信息
|
||||||
'time0': None, # 定位首次出现时间戳
|
'time0': None, # 定位首次出现时间戳
|
||||||
"time1": None, # 首次在该区域时间戳
|
"time1": None, # 首次在该区域时间戳
|
||||||
"time2": int(time.time()), # 当前时间戳
|
"time2": int(time.time()), # 当前时间戳
|
||||||
|
@ -82,8 +85,9 @@ def notify_event(event: Event):
|
||||||
"""
|
"""
|
||||||
# 生成通知文本
|
# 生成通知文本
|
||||||
ep = event.employee
|
ep = event.employee
|
||||||
|
obj_cate = event.obj_cate
|
||||||
params = {'area': event.area.name, 'employee': '', 'event': ''}
|
params = {'area': event.area.name, 'employee': '', 'event': ''}
|
||||||
if ep:
|
if obj_cate == 'people' and ep:
|
||||||
ep_name = ep.name
|
ep_name = ep.name
|
||||||
ep_type = '员工'
|
ep_type = '员工'
|
||||||
if ep.type == 'rempoyee':
|
if ep.type == 'rempoyee':
|
||||||
|
@ -91,8 +95,10 @@ def notify_event(event: Event):
|
||||||
elif ep.type == 'visitor':
|
elif ep.type == 'visitor':
|
||||||
ep_type = '访客'
|
ep_type = '访客'
|
||||||
params['employee'] = ep_type + ep_name
|
params['employee'] = ep_type + ep_name
|
||||||
else:
|
elif obj_cate == 'people':
|
||||||
params['employee'] = '未知人员'
|
params['employee'] = '未知人员'
|
||||||
|
elif obj_cate == 'area':
|
||||||
|
params['employee'] = '区域'
|
||||||
for i in event.cates.all():
|
for i in event.cates.all():
|
||||||
params['event'] = params['event'] + i.name + ','
|
params['event'] = params['event'] + i.name + ','
|
||||||
event.voice_msg = '位于{}的{},{}请及时处理'.format(params['area'], params['employee'], params['event'])
|
event.voice_msg = '位于{}的{},{}请及时处理'.format(params['area'], params['employee'], params['event'])
|
||||||
|
@ -113,10 +119,11 @@ def save_voice_and_speak(event: Event):
|
||||||
v_p, v_num = main_cate.voice_person, main_cate.voice_num
|
v_p, v_num = main_cate.voice_person, main_cate.voice_num
|
||||||
_, event.voice, _ = generate_voice(event.voice_msg, v_p)
|
_, event.voice, _ = generate_voice(event.voice_msg, v_p)
|
||||||
event.save()
|
event.save()
|
||||||
sps = list(TDevice.objects.filter(area=event.area, type=TDevice.DEVICE_SPEAKER).values_list('code', flat=True))
|
if event.area: # 如果事件存在发生区域
|
||||||
if len(sps) == 0: # 如果当前区域没有喇叭就找覆盖区的喇叭
|
sps = list(TDevice.objects.filter(area=event.area, type=TDevice.DEVICE_SPEAKER).values_list('code', flat=True))
|
||||||
sps = list(TDevice.objects.filter(areas=event.area,
|
if len(sps) == 0: # 如果当前区域没有喇叭就找覆盖区的喇叭
|
||||||
type=TDevice.DEVICE_SPEAKER).values_list('code', flat=True))
|
sps = list(TDevice.objects.filter(areas=event.area,
|
||||||
|
type=TDevice.DEVICE_SPEAKER).values_list('code', flat=True))
|
||||||
# 查找固定喇叭
|
# 查找固定喇叭
|
||||||
for m in event.cates.all():
|
for m in event.cates.all():
|
||||||
for n in m.speakers.all():
|
for n in m.speakers.all():
|
||||||
|
@ -212,7 +219,6 @@ def dispatch_dahua_event(data: dict):
|
||||||
alarm_type = data['info']['alarmType']
|
alarm_type = data['info']['alarmType']
|
||||||
vchannel = TDevice.objects.filter(code=vchannel_code).first()
|
vchannel = TDevice.objects.filter(code=vchannel_code).first()
|
||||||
event = None
|
event = None
|
||||||
print(data)
|
|
||||||
if alarm_type in [1001003, 1001000] and vchannel: # 内部人员/或陌生人报警
|
if alarm_type in [1001003, 1001000] and vchannel: # 内部人员/或陌生人报警
|
||||||
# 查看加载的算法
|
# 查看加载的算法
|
||||||
algo_codes = list(AlgoChannel.objects.filter(vchannel=vchannel).exclude(
|
algo_codes = list(AlgoChannel.objects.filter(vchannel=vchannel).exclude(
|
||||||
|
@ -260,47 +266,37 @@ def dispatch_xunxi_event(data: dict):
|
||||||
rail_out(data=data.data)
|
rail_out(data=data.data)
|
||||||
elif data.type == 'onKeyAlarm':
|
elif data.type == 'onKeyAlarm':
|
||||||
# 一键呼救
|
# 一键呼救
|
||||||
one_key_alarm(data=data)
|
handle_xx_event(name='one_key_alarm', data=data)
|
||||||
elif data.type == 'location':
|
elif data.type == 'location':
|
||||||
# 定位信息
|
# 定位信息
|
||||||
loc_change(data=data)
|
loc_change(data=data)
|
||||||
elif data.type == 'onOffLine':
|
elif data.type == 'onOffLine':
|
||||||
if data.data.online:
|
if data.data.online:
|
||||||
# 标签定位在线
|
# 标签定位在线
|
||||||
pass
|
blt_online(data=data.data)
|
||||||
else:
|
else:
|
||||||
# 标签定位离线
|
# 标签定位离线
|
||||||
pass
|
blt_offline(data=data.data)
|
||||||
elif data.type == 'lowpower':
|
elif data.type == 'lowpower':
|
||||||
# 低电量
|
# 低电量
|
||||||
low_power(data=data.data)
|
handle_xx_event(name='low_power', data=data)
|
||||||
elif data.type == 'bltOnOffLineV2':
|
elif data.type == 'bltOnOffLineV2':
|
||||||
if data.data.online:
|
if data.data.online:
|
||||||
# 标签通信在线
|
# 标签通信在线
|
||||||
blt_online(data=data.data)
|
pass
|
||||||
else:
|
else:
|
||||||
# 标签通信离线
|
# 标签通信离线
|
||||||
blt_offline(data=data.data)
|
pass
|
||||||
|
|
||||||
|
|
||||||
def rail_in(data):
|
def rail_in(data):
|
||||||
"""围栏进入事件
|
"""围栏进入
|
||||||
"""
|
"""
|
||||||
# 找到所在围栏
|
# 找到所在围栏
|
||||||
area = Area.objects.filter(third_info__xx_rail__id=data['railId']).first()
|
area = Area.objects.filter(third_info__xx_rail__id=data['railId']).first()
|
||||||
# 找到进入对象
|
# 找到进入对象
|
||||||
blts = TDevice.objects.filter(code=data['userId']).first()
|
blts = TDevice.objects.filter(code=data['userId']).first()
|
||||||
if area and blts and blts.employee: # 如果是人
|
if area and blts and blts.employee: # 如果是人
|
||||||
if area.type == Area.AREA_TYPE_FIX: # 如果是固定区域
|
|
||||||
# 更新人员位置信息缓存
|
|
||||||
key_str = 'ep_{}'.format(blts.employee.id)
|
|
||||||
ep_loc_dict = cache.get_or_set(
|
|
||||||
key_str, get_ep_default(), timeout=None
|
|
||||||
)
|
|
||||||
if ep_loc_dict['area_fix_id'] != area.id: # 如果区域未变化则不动
|
|
||||||
ep_loc_dict['time1'] = ep_loc_dict['time2']
|
|
||||||
ep_loc_dict['area_fix_id'] = area.id
|
|
||||||
cache.set(key_str, ep_loc_dict)
|
|
||||||
ep_blt = blts.employee # 标签绑定人员
|
ep_blt = blts.employee # 标签绑定人员
|
||||||
if ep_blt:
|
if ep_blt:
|
||||||
for i in Access.objects.filter(area=area).order_by('sort'):
|
for i in Access.objects.filter(area=area).order_by('sort'):
|
||||||
|
@ -310,28 +306,28 @@ def rail_in(data):
|
||||||
if ep_blt in eps_access and i.type == Access.ACCESS_IN_YES:
|
if ep_blt in eps_access and i.type == Access.ACCESS_IN_YES:
|
||||||
return
|
return
|
||||||
elif ep_blt in eps_access and i.type == Access.ACCESS_IN_NO:
|
elif ep_blt in eps_access and i.type == Access.ACCESS_IN_NO:
|
||||||
# 触发非法进入事件
|
# 触发违规进入事件
|
||||||
pass
|
handle_xx_event_2('i_enter', ep=ep_blt, area=area)
|
||||||
elif i.dept: # 如果是按部门设定的
|
elif i.dept: # 如果是按部门设定的
|
||||||
if i.dept.type == 'dept': # 如果是内部部门
|
if i.dept.type == 'dept': # 如果是内部部门
|
||||||
depts = get_child_queryset2(i.dept)
|
depts = get_child_queryset2(i.dept)
|
||||||
if ep_blt.belong_dept in depts and i.type == Access.ACCESS_IN_YES:
|
if ep_blt.belong_dept in depts and i.type == Access.ACCESS_IN_YES:
|
||||||
return
|
return
|
||||||
elif ep_blt.belong_dept in depts and i.type == Access.ACCESS_IN_NO:
|
elif ep_blt.belong_dept in depts and i.type == Access.ACCESS_IN_NO:
|
||||||
# 触发非法进入事件
|
# 触发违规进入事件
|
||||||
pass
|
handle_xx_event_2('i_enter', ep=ep_blt, area=area)
|
||||||
elif i.dept.type == 'rparty': # 如果是相关方
|
elif i.dept.type == 'rparty': # 如果是相关方
|
||||||
if ep_blt.belong_dept == i.dept and i.type == Access.ACCESS_IN_YES:
|
if ep_blt.belong_dept == i.dept and i.type == Access.ACCESS_IN_YES:
|
||||||
return
|
return
|
||||||
elif ep_blt.belong_dept == i.dept and i.type == Access.ACCESS_IN_NO:
|
elif ep_blt.belong_dept == i.dept and i.type == Access.ACCESS_IN_NO:
|
||||||
# 触发非法进入事件
|
# 触发违规进入事件
|
||||||
pass
|
handle_xx_event_2('i_enter', ep=ep_blt, area=area)
|
||||||
elif i.employee: # 如果是按人设定的
|
elif i.employee: # 如果是按人设定的
|
||||||
if ep_blt == i.employee and i.type == Access.ACCESS_IN_YES:
|
if ep_blt == i.employee and i.type == Access.ACCESS_IN_YES:
|
||||||
return
|
return
|
||||||
elif ep_blt == i.employee and i.type == Access.ACCESS_IN_NO:
|
elif ep_blt == i.employee and i.type == Access.ACCESS_IN_NO:
|
||||||
# 触发非法进入事件
|
# 触发违规进入事件
|
||||||
pass
|
handle_xx_event_2('i_enter', ep=ep_blt, area=area)
|
||||||
# 通用权限设置过滤
|
# 通用权限设置过滤
|
||||||
if ep_blt.type == 'employee' and area.employee_yes:
|
if ep_blt.type == 'employee' and area.employee_yes:
|
||||||
return
|
return
|
||||||
|
@ -340,72 +336,185 @@ def rail_in(data):
|
||||||
elif ep_blt.type == 'visitor' and area.visitor_yes:
|
elif ep_blt.type == 'visitor' and area.visitor_yes:
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
# 触发非法进入事件
|
# 触发违规进入事件
|
||||||
pass
|
handle_xx_event_2('i_enter', ep=ep_blt, area=area)
|
||||||
elif area and (not blts):
|
# elif area and (not blts):
|
||||||
# 触发未知标签进入事件
|
# # 触发未知标签进入事件
|
||||||
pass
|
# e_i_enter(ep=ep_blt, area=area)
|
||||||
|
|
||||||
|
|
||||||
def rail_out(data):
|
def rail_out(data):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def low_power(data):
|
|
||||||
# 有绑定对象再提示低电量
|
|
||||||
blts = TDevice.objects.filter(code=data['userId']).first()
|
|
||||||
if blts.employee:
|
|
||||||
# 触发低电量提醒事件
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def one_key_alarm(data):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def loc_change(data):
|
def loc_change(data):
|
||||||
blts = TDevice.objects.filter(code=data['userId']).first()
|
blts = TDevice.objects.filter(code=data['userId']).first()
|
||||||
if blts.employee:
|
if blts.employee:
|
||||||
# 从缓存查询人员位置信息
|
# 从缓存查询人员位置信息
|
||||||
time2 = int(time.time())
|
|
||||||
key_str = 'ep_{}'.format(blts.employee.id)
|
key_str = 'ep_{}'.format(blts.employee.id)
|
||||||
ep_loc_dict = cache.get_or_set(
|
ep_loc_dict = cache.get_or_set(
|
||||||
key_str, get_ep_default(), timeout=None
|
key_str, get_ep_default(), timeout=None
|
||||||
)
|
)
|
||||||
|
ep_loc_dict['time2'] = int(time.time())
|
||||||
|
ep_loc_dict['xx_detail'] = data
|
||||||
|
|
||||||
|
area_fix, area_temp = get_area_from_point(data['xMillimeter'], data['yMillimeter'], data['floorNo'])
|
||||||
|
time2 = int(time.time())
|
||||||
|
ep_loc_dict['area_temp_id'] = area_temp['id'] if area_temp else None
|
||||||
ep_loc_dict['time2'] = time2
|
ep_loc_dict['time2'] = time2
|
||||||
# 从缓存里获取固定区域列表信息
|
if area_fix and ep_loc_dict['area_fix_id'] == area_fix['id']:
|
||||||
area_fix_list = cache.get('area_fix_list', None)
|
# 如果停留在该区域
|
||||||
if not area_fix_list:
|
cache.set(key_str, ep_loc_dict)
|
||||||
area_fix_list = cache_areas_info()
|
# 在该固定区域停留时间(分钟)
|
||||||
if ep_loc_dict.get('area_fix_id', None):
|
stay_minute = int((ep_loc_dict['time2']-ep_loc_dict['time1'])/60)
|
||||||
# 如果存在所在固定区域
|
# 判断停留时间是否合理
|
||||||
area_info = get_area_info_from_cache(ep_loc_dict['area_fix_id'], area_fix_list)
|
# 先通过自定义权限过滤(暂未做)
|
||||||
if area_info:
|
# 再经过通用设置过滤
|
||||||
# 在该固定区域停留时间(分钟)
|
if 0 < stay_minute < area_fix['stay_minute_min']:
|
||||||
stay_minute = int((ep_loc_dict['time2']-ep_loc_dict['time1'])/60)
|
# 触发离岗事件
|
||||||
# 判断停留时间是否合理
|
handle_xx_event_2('leave_area', ep=blts.employee, area=Area.objects.get(id=area_fix['id']))
|
||||||
# 先通过自定义权限过滤(暂未做)
|
elif area_fix['stay_minute_max'] < stay_minute:
|
||||||
# 再经过通用设置过滤
|
# 触发超时滞留事件
|
||||||
if 0 < stay_minute < area_info['stay_minute_min']:
|
handle_xx_event_2('stand_area', ep=blts.employee, area=Area.objects.get(id=area_fix['id']))
|
||||||
# 触发离岗事件
|
|
||||||
return
|
|
||||||
elif area_info['stay_minute_max'] < stay_minute:
|
|
||||||
# 触发超时滞留事件
|
|
||||||
return
|
|
||||||
else:
|
else:
|
||||||
for i in area_fix_list:
|
ep_loc_dict['time1'] = time2
|
||||||
if data['floorNo'] == i['floor_no']:
|
ep_loc_dict['area_fix_id'] = area_fix['id'] if area_fix else None
|
||||||
point = Point(data['xMillimeter'], data['yMillimeter'])
|
cache.set(key_str, ep_loc_dict)
|
||||||
if i['polygon'].intersects(point): # 如果点在多边形中
|
|
||||||
ep_loc_dict['time1'] = time2
|
|
||||||
ep_loc_dict['are_id'] = i['area_fix_id']
|
def handle_xx_event(name: str, data: dict):
|
||||||
ep_loc_dict['time2'] = time2
|
# 有绑定对象再提示事件
|
||||||
cache.set(key_str, ep_loc_dict)
|
blts = TDevice.objects.filter(code=data['userId']).first()
|
||||||
|
if blts.employee:
|
||||||
|
# 触发事件
|
||||||
|
cate = EventCate.objects.filter(code=name).first()
|
||||||
|
if cate:
|
||||||
|
event = Event()
|
||||||
|
# 查询定位信息
|
||||||
|
key_str = 'ep_{}'.format(blts.employee.id)
|
||||||
|
ep_loc_dict = cache.get(key_str, None)
|
||||||
|
if ep_loc_dict:
|
||||||
|
if ep_loc_dict['area_fix_id']:
|
||||||
|
event.area = Area.objects.get(id=ep_loc_dict['area_fix_id'])
|
||||||
|
event.location = ep_loc_dict['xx_detail']
|
||||||
|
event.obj_cate = 'people'
|
||||||
|
event.employee = blts.employee
|
||||||
|
event.happen_time = timezone.now()
|
||||||
|
event.save()
|
||||||
|
Eventdo.objects.get_or_create(cate=cate, event=event, defaults={
|
||||||
|
'cate': cate,
|
||||||
|
'event': event
|
||||||
|
})
|
||||||
|
notify_event(event)
|
||||||
|
|
||||||
|
|
||||||
|
def handle_xx_event_2(name: str, ep: Employee, area: Area):
|
||||||
|
# 违规进入事件特殊处理
|
||||||
|
# 找寻该区域下审批和进行的作业, 本厂或相关方人员, 如是就不触发
|
||||||
|
if name == 'i_enter' and ep.type in ['employee', 'remployee']:
|
||||||
|
ops = Operation.objects.filter(area=area, state__in=[Operation.OP_AUDIT, Operation.OP_WAIT, Operation.OP_WORK])
|
||||||
|
if OplWorker.objects.filter(opl__operation__in=ops, worker__employee=ep).exists():
|
||||||
|
# 如果是作业人员
|
||||||
|
return
|
||||||
|
elif ops.filter(coordinator__employee=ep).exists():
|
||||||
|
# 如果是协调员
|
||||||
|
return
|
||||||
|
elif Opl.objects.filter(operation=ops, charger__employee=ep).exists():
|
||||||
|
# 如果是作业负责人
|
||||||
|
return
|
||||||
|
elif Opl.objects.filter(operation=ops, monitor__employee=ep).exists():
|
||||||
|
# 如果是作业监护人
|
||||||
|
return
|
||||||
|
cate = EventCate.objects.filter(code=name).first()
|
||||||
|
if cate:
|
||||||
|
event = Event()
|
||||||
|
event.area = area
|
||||||
|
# 查询定位信息
|
||||||
|
key_str = 'ep_{}'.format(ep.id)
|
||||||
|
ep_loc_dict = cache.get(key_str, None)
|
||||||
|
if ep_loc_dict:
|
||||||
|
event.location = ep_loc_dict['xx_detail']
|
||||||
|
event.obj_cate = 'people'
|
||||||
|
event.employee = ep
|
||||||
|
event.happen_time = timezone.now()
|
||||||
|
event.save()
|
||||||
|
Eventdo.objects.get_or_create(cate=cate, event=event, defaults={
|
||||||
|
'cate': cate,
|
||||||
|
'event': event
|
||||||
|
})
|
||||||
|
notify_event(event)
|
||||||
|
|
||||||
|
|
||||||
def blt_online(data):
|
def blt_online(data):
|
||||||
pass
|
# 定位在线
|
||||||
|
blts = TDevice.objects.filter(code=data['userId']).first()
|
||||||
|
if blts.employee:
|
||||||
|
ep = blts.employee
|
||||||
|
if ep.type == 'employee' and ep.is_at_work is False:
|
||||||
|
# 上班打卡
|
||||||
|
now = timezone.now()
|
||||||
|
cr_10 = ClockRecord.objects.filter(type=10, employee=ep, create_time__year=now.year,
|
||||||
|
create_time__month=now.month, create_time__day=now.day).first()
|
||||||
|
if cr_10:
|
||||||
|
if now < cr_10.create_by:
|
||||||
|
cr_10.create_by = now
|
||||||
|
cr_10.trigger = 'location'
|
||||||
|
cr_10.detail = data
|
||||||
|
cr_10.save()
|
||||||
|
else:
|
||||||
|
cr_10 = ClockRecord()
|
||||||
|
cr_10.type = 10
|
||||||
|
cr_10.employee = ep
|
||||||
|
cr_10.trigger = 'location'
|
||||||
|
cr_10.detail = data
|
||||||
|
cr_10.save()
|
||||||
|
ep.is_at_work = True
|
||||||
|
ep.save()
|
||||||
|
|
||||||
|
|
||||||
def blt_offline(data):
|
def blt_offline(data):
|
||||||
pass
|
blts = TDevice.objects.filter(code=data['userId']).first()
|
||||||
|
# 定位离线
|
||||||
|
if blts.employee:
|
||||||
|
ep = blts.employee
|
||||||
|
if ep.type == 'employee' and ep.is_at_work:
|
||||||
|
# 下班打卡
|
||||||
|
now = timezone.now()
|
||||||
|
cr_20 = ClockRecord.objects.filter(type=20, employee=ep, create_time__year=now.year,
|
||||||
|
create_time__month=now.month, create_time__day=now.day).first()
|
||||||
|
if cr_20:
|
||||||
|
if now > cr_20.create_by:
|
||||||
|
cr_20.create_by = now
|
||||||
|
cr_20.trigger = 'location'
|
||||||
|
cr_20.detail = data
|
||||||
|
cr_20.save()
|
||||||
|
else:
|
||||||
|
cr_20 = ClockRecord()
|
||||||
|
cr_20.type = 20
|
||||||
|
cr_20.employee = ep
|
||||||
|
cr_20.trigger = 'location'
|
||||||
|
cr_20.detail = data
|
||||||
|
cr_20.save()
|
||||||
|
ep.is_at_work = False
|
||||||
|
ep.save()
|
||||||
|
|
||||||
|
|
||||||
|
def get_area_from_point(x: int, y: int, floorNo: str):
|
||||||
|
"""
|
||||||
|
从位置信息获取所在固定区域
|
||||||
|
返回一个固定区域, 一个临时区域
|
||||||
|
"""
|
||||||
|
area_fix = None
|
||||||
|
area_temp = None
|
||||||
|
area_list = cache.get('area_list', None)
|
||||||
|
if not area_list:
|
||||||
|
area_list = cache_areas_info()
|
||||||
|
point = Point(x, y)
|
||||||
|
for i in area_list:
|
||||||
|
if floorNo == i['floor_no']:
|
||||||
|
if i['polygon'].intersects(point): # 如果点在多边形中
|
||||||
|
if i['type'] == Area.AREA_TYPE_FIX:
|
||||||
|
area_fix = i
|
||||||
|
elif i['type'] == Area.AREA_TYPE_TEMP:
|
||||||
|
area_temp = i
|
||||||
|
return area_fix, area_temp
|
||||||
|
|
|
@ -5,6 +5,8 @@ from threading import Thread
|
||||||
from celery import shared_task
|
from celery import shared_task
|
||||||
|
|
||||||
from apps.am.models import Area
|
from apps.am.models import Area
|
||||||
|
from apps.ecm.models import EventCate, Eventdo
|
||||||
|
from apps.ecm.service import notify_event
|
||||||
from apps.third.clients import xxClient
|
from apps.third.clients import xxClient
|
||||||
from apps.third.models import TDevice
|
from apps.third.models import TDevice
|
||||||
from apps.third.tapis import xxapis
|
from apps.third.tapis import xxapis
|
||||||
|
@ -26,10 +28,25 @@ def update_count_people(i: Area):
|
||||||
i.save()
|
i.save()
|
||||||
if i.count_people >= i.count_people_max:
|
if i.count_people >= i.count_people_max:
|
||||||
# 触发超员事件
|
# 触发超员事件
|
||||||
pass
|
handle_xx_event_3('over_man', i)
|
||||||
elif i.count_people < i.count_people_min:
|
elif i.count_people < i.count_people_min:
|
||||||
# 触发缺员事件
|
# 触发缺员事件
|
||||||
pass
|
handle_xx_event_3('lack_man', i)
|
||||||
|
|
||||||
|
|
||||||
|
def handle_xx_event_3(name: str, area: Area):
|
||||||
|
cate = EventCate.objects.filter(code=name).first()
|
||||||
|
if cate:
|
||||||
|
event = Event()
|
||||||
|
event.area = area
|
||||||
|
event.obj_cate = 'area'
|
||||||
|
event.happen_time = timezone.now()
|
||||||
|
event.save()
|
||||||
|
Eventdo.objects.get_or_create(cate=cate, event=event, defaults={
|
||||||
|
'cate': cate,
|
||||||
|
'event': event
|
||||||
|
})
|
||||||
|
notify_event(event)
|
||||||
|
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
|
@ -50,5 +67,3 @@ def check_event_timeout():
|
||||||
if cate.hanle_minute > 0 and (timezone.now()-i.create_time).seconds > cate.hanle_minute * 60:
|
if cate.hanle_minute > 0 and (timezone.now()-i.create_time).seconds > cate.hanle_minute * 60:
|
||||||
i.is_timeout = True
|
i.is_timeout = True
|
||||||
i.save()
|
i.save()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ class ClockRecordFilterSet(filters.FilterSet):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ClockRecord
|
model = ClockRecord
|
||||||
fields = ['create_by', 'create_time_start', 'create_time_end', 'year', 'month']
|
fields = ['employee', 'create_time_start', 'create_time_end', 'year', 'month']
|
||||||
|
|
||||||
def filter_year(self, queryset, name, value):
|
def filter_year(self, queryset, name, value):
|
||||||
return queryset.filter(create_time_date__year=value)
|
return queryset.filter(create_time_date__year=value)
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
# Generated by Django 3.2.12 on 2022-08-10 07:12
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('hrm', '0005_alter_employee_phone'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='clockrecord',
|
||||||
|
name='create_by',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='clockrecord',
|
||||||
|
name='update_by',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='clockrecord',
|
||||||
|
name='detail',
|
||||||
|
field=models.JSONField(blank=True, default=dict, verbose_name='相关记录'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='clockrecord',
|
||||||
|
name='employee',
|
||||||
|
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='hrm.employee', verbose_name='对应人员'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='clockrecord',
|
||||||
|
name='trigger',
|
||||||
|
field=models.CharField(default='door', max_length=20, verbose_name='触发'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='clockrecord',
|
||||||
|
name='type',
|
||||||
|
field=models.PositiveSmallIntegerField(choices=[(10, '上班打卡'), (20, '下班打卡')], default=10, verbose_name='打卡类型'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='employee',
|
||||||
|
name='user',
|
||||||
|
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='employee', to=settings.AUTH_USER_MODEL, verbose_name='系统账号'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,7 +1,7 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from apps.system.models import Post, User
|
from apps.system.models import Post, User
|
||||||
|
|
||||||
from apps.utils.models import CommonADModel, CommonAModel, CommonBModel
|
from apps.utils.models import BaseModel, CommonADModel, CommonAModel, CommonBModel
|
||||||
|
|
||||||
|
|
||||||
class Employee(CommonBModel):
|
class Employee(CommonBModel):
|
||||||
|
@ -22,6 +22,7 @@ class Employee(CommonBModel):
|
||||||
type = models.CharField('人员类型', default='employee', max_length=10, choices=PEOPLE_TYPE_CHOICES)
|
type = models.CharField('人员类型', default='employee', max_length=10, choices=PEOPLE_TYPE_CHOICES)
|
||||||
user = models.OneToOneField(User,
|
user = models.OneToOneField(User,
|
||||||
verbose_name='系统账号',
|
verbose_name='系统账号',
|
||||||
|
related_name='employee',
|
||||||
on_delete=models.PROTECT, null=True, blank=True)
|
on_delete=models.PROTECT, null=True, blank=True)
|
||||||
name = models.CharField('姓名', max_length=20)
|
name = models.CharField('姓名', max_length=20)
|
||||||
phone = models.CharField('手机号', max_length=11, null=True, blank=True, unique=True)
|
phone = models.CharField('手机号', max_length=11, null=True, blank=True, unique=True)
|
||||||
|
@ -69,15 +70,20 @@ class NotWorkRemark(CommonAModel):
|
||||||
remark = models.CharField('未打卡说明', null=True, blank=True, max_length=200)
|
remark = models.CharField('未打卡说明', null=True, blank=True, max_length=200)
|
||||||
|
|
||||||
|
|
||||||
class ClockRecord(CommonADModel):
|
class ClockRecord(BaseModel):
|
||||||
"""
|
"""
|
||||||
打卡记录
|
打卡记录
|
||||||
"""
|
"""
|
||||||
ClOCK_WORK1 = 10
|
ClOCK_ON = 10
|
||||||
|
CLOCK_OFF = 20
|
||||||
type_choice = (
|
type_choice = (
|
||||||
(ClOCK_WORK1, '上班打卡'),
|
(ClOCK_ON, '上班打卡'),
|
||||||
|
(CLOCK_OFF, '下班打卡'),
|
||||||
)
|
)
|
||||||
type = models.PositiveSmallIntegerField('打卡类型', choices=type_choice, default=ClOCK_WORK1)
|
type = models.PositiveSmallIntegerField('打卡类型', choices=type_choice, default=ClOCK_ON)
|
||||||
|
employee = models.ForeignKey(Employee, verbose_name='对应人员', on_delete=models.CASCADE)
|
||||||
|
trigger = models.CharField('触发', max_length=20)
|
||||||
|
detail = models.JSONField('相关记录', default=dict, null=False, blank=True)
|
||||||
|
|
||||||
|
|
||||||
class Certificate(CommonAModel):
|
class Certificate(CommonAModel):
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
from apps.hrm.models import Employee
|
from apps.hrm.models import ClockRecord, Employee
|
||||||
from apps.third.models import TDevice
|
from apps.third.models import TDevice
|
||||||
from apps.third.tapis import dhapis
|
from apps.third.tapis import dhapis
|
||||||
from apps.third.clients import dhClient
|
from apps.third.clients import dhClient
|
||||||
from apps.utils.tools import rannum, ranstr
|
from apps.utils.tools import rannum, ranstr
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
class HrmService:
|
class HrmService:
|
||||||
|
|
||||||
|
@ -193,7 +193,53 @@ class HrmService:
|
||||||
"""
|
"""
|
||||||
deviceCode = data['infoArray']['deviceCode']
|
deviceCode = data['infoArray']['deviceCode']
|
||||||
device = TDevice.objects.filter(code=deviceCode).first()
|
device = TDevice.objects.filter(code=deviceCode).first()
|
||||||
if not device:
|
if device and device.is_clock:
|
||||||
device = TDevice.objects.create(type=TDevice.DEVICE_DCHANNEL, code=deviceCode)
|
# 如果设置为关联考勤
|
||||||
if device.is_clock:
|
if data['info']['extend']['enterOrExit'] == "1":
|
||||||
pass
|
# 如果是进门
|
||||||
|
id_number = data['info']['extend']['paperNumber']
|
||||||
|
if id_number:
|
||||||
|
ep = Employee.objects.filter(id_number=id_number, type="employee").first()
|
||||||
|
# 如果是内部员工创建上班打卡记录(更新)
|
||||||
|
if ep and ep.is_at_work is False:
|
||||||
|
now = timezone.now()
|
||||||
|
cr_10 = ClockRecord.objects.filter(type=10, employee=ep, create_time__year=now.year, create_time__month=now.month, create_time__day=now.day).first()
|
||||||
|
if cr_10:
|
||||||
|
if now < cr_10.create_by:
|
||||||
|
cr_10.create_by = now
|
||||||
|
cr_10.trigger = 'door'
|
||||||
|
cr_10.detail = data['info']['extend']
|
||||||
|
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.save()
|
||||||
|
ep.is_at_work = True
|
||||||
|
ep.save()
|
||||||
|
elif data['info']['extend']['enterOrExit'] == "2":
|
||||||
|
# 如果是出门
|
||||||
|
id_number = data['info']['extend']['paperNumber']
|
||||||
|
if id_number:
|
||||||
|
ep = Employee.objects.filter(id_number=id_number, type="employee").first()
|
||||||
|
# 如果是内部员工创建下班打卡记录(更新)
|
||||||
|
if ep and ep.is_at_work:
|
||||||
|
now = timezone.now()
|
||||||
|
cr_20 = ClockRecord.objects.filter(type=20, employee=ep, create_time__year=now.year, create_time__month=now.month, create_time__day=now.day).first()
|
||||||
|
if cr_20:
|
||||||
|
if now > cr_20.create_by:
|
||||||
|
cr_20.create_by = now
|
||||||
|
cr_20.trigger = 'door'
|
||||||
|
cr_20.detail = data['info']['extend']
|
||||||
|
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.save()
|
||||||
|
ep.is_at_work = False
|
||||||
|
ep.save()
|
||||||
|
|
|
@ -207,7 +207,7 @@ class ClockRecordViewSet(ListModelMixin, CustomGenericViewSet):
|
||||||
authentication_classes = []
|
authentication_classes = []
|
||||||
permission_classes = [AllowAny]
|
permission_classes = [AllowAny]
|
||||||
queryset = ClockRecord.objects.all()
|
queryset = ClockRecord.objects.all()
|
||||||
select_related_fields = ['create_by']
|
select_related_fields = ['employee']
|
||||||
serializer_class = ClockRecordListSerializer
|
serializer_class = ClockRecordListSerializer
|
||||||
filterset_class = ClockRecordFilterSet
|
filterset_class = ClockRecordFilterSet
|
||||||
ordering = ['-pk']
|
ordering = ['-pk']
|
||||||
|
|
|
@ -61,4 +61,5 @@ def opl_audit_end(ticket: Ticket):
|
||||||
op.save()
|
op.save()
|
||||||
|
|
||||||
# 授予相关工作人员区域进入权限
|
# 授予相关工作人员区域进入权限
|
||||||
worker_ep_ids = list(OplWorker.objects.filter(opl=opl).values_list('worker__id', flat=True))
|
# worker_ep_ids = list(OplWorker.objects.filter(opl=opl).values_list('worker__id', flat=True))
|
||||||
|
# 发送通知
|
||||||
|
|
|
@ -9,8 +9,10 @@ from rest_framework.exceptions import APIException, ParseError
|
||||||
|
|
||||||
from apps.third.errors import DH_REQUEST_ERROR
|
from apps.third.errors import DH_REQUEST_ERROR
|
||||||
from apps.third.models import Tlog
|
from apps.third.models import Tlog
|
||||||
|
from apps.utils.my_rsa import encrypt_data
|
||||||
from apps.utils.tools import print_roundtrip
|
from apps.utils.tools import print_roundtrip
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
|
from apps.third.tapis import dhapis
|
||||||
|
|
||||||
requests.packages.urllib3.disable_warnings()
|
requests.packages.urllib3.disable_warnings()
|
||||||
|
|
||||||
|
@ -139,4 +141,18 @@ class DhClient:
|
||||||
}
|
}
|
||||||
if '$' in code:
|
if '$' in code:
|
||||||
d_code = code.split('$')[0]
|
d_code = code.split('$')[0]
|
||||||
json_data['deviceCode'] = d_code
|
json_data['deviceCode'] = d_code
|
||||||
|
|
||||||
|
def get_password_token(self):
|
||||||
|
_, res = self.request(**dhapis['oauth_key'])
|
||||||
|
e_pwd = encrypt_data(settings.DAHUA_PASSWORD, res['publicKey'])
|
||||||
|
res['public_key'] = res['publicKey']
|
||||||
|
res['password'] = e_pwd
|
||||||
|
res.update({
|
||||||
|
"grant_type": "password",
|
||||||
|
"username": settings.DAHUA_USERNAME,
|
||||||
|
"client_id": settings.DAHUA_CLIENTID,
|
||||||
|
"client_secret": settings.DAHUA_SECRET,
|
||||||
|
})
|
||||||
|
_, res2 = self.request(**dhapis['oauth_token'], json=res)
|
||||||
|
return res2
|
||||||
|
|
|
@ -107,6 +107,14 @@ dhapis = {
|
||||||
"close_door": {
|
"close_door": {
|
||||||
"url": "/evo-apigw/evo-accesscontrol/1.2.0/card/accessControl/channelControl/closeDoor",
|
"url": "/evo-apigw/evo-accesscontrol/1.2.0/card/accessControl/channelControl/closeDoor",
|
||||||
"method": "post"
|
"method": "post"
|
||||||
|
},
|
||||||
|
"oauth_key": {
|
||||||
|
"url": "/evo-apigw/evo-oauth/1.0.0/oauth/public-key",
|
||||||
|
"method": "get"
|
||||||
|
},
|
||||||
|
"oauth_token": {
|
||||||
|
"url": "/evo-apigw/evo-oauth/1.0.0/oauth/extend/token",
|
||||||
|
"method": "post"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +151,7 @@ xxapis = {
|
||||||
"blt_info": {
|
"blt_info": {
|
||||||
"url": "/api/devicesV3/bltInfoByMac",
|
"url": "/api/devicesV3/bltInfoByMac",
|
||||||
"method": "post"
|
"method": "post"
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,9 +27,7 @@ class DahuaTestView(MyLoggingMixin, APIView):
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
_, res = dhClient.request(
|
res = dhClient.get_password_token()
|
||||||
url='/evo-apigw/evo-brm/1.0.0/person/subsystem/{}'.format(2059335),
|
|
||||||
method='get')
|
|
||||||
return Response(res)
|
return Response(res)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
import base64
|
||||||
|
from Crypto.PublicKey import RSA
|
||||||
|
from Crypto.Hash import SHA
|
||||||
|
from Crypto.Signature import PKCS1_v1_5 as PKCS1_signature
|
||||||
|
from Crypto.Cipher import PKCS1_v1_5 as PKCS1_cipher
|
||||||
|
|
||||||
|
|
||||||
|
def encrypt_data(msg, pub_key):
|
||||||
|
pub_key = '-----BEGIN RSA PUBLIC KEY-----\n'+pub_key+'\n-----END RSA PUBLIC KEY-----'
|
||||||
|
public_key = RSA.importKey(pub_key)
|
||||||
|
cipher = PKCS1_cipher.new(public_key)
|
||||||
|
encrypt_text = base64.b64encode(cipher.encrypt(bytes(msg.encode("utf8"))))
|
||||||
|
return encrypt_text.decode('utf-8')
|
|
@ -86,13 +86,6 @@ class WfService(object):
|
||||||
nsteps_list.append(i)
|
nsteps_list.append(i)
|
||||||
return nsteps_list
|
return nsteps_list
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_ticket_transitions(cls, ticket: Ticket):
|
|
||||||
"""
|
|
||||||
获取工单可执行的操作
|
|
||||||
"""
|
|
||||||
return cls.get_state_transitions(ticket.state)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_transition_by_args(cls, kwargs: dict):
|
def get_transition_by_args(cls, kwargs: dict):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -27,3 +27,4 @@ requests==2.28.1
|
||||||
grpcio==1.47.0
|
grpcio==1.47.0
|
||||||
grpcio-tools==1.47.0
|
grpcio-tools==1.47.0
|
||||||
protobuf==3.20.1
|
protobuf==3.20.1
|
||||||
|
pycryptodome==3.15.0
|
||||||
|
|
Loading…
Reference in New Issue