区域表修改

This commit is contained in:
曹前明 2022-06-27 08:37:28 +08:00
parent 41ae3551eb
commit ab669192bf
9 changed files with 198 additions and 42 deletions

View File

@ -0,0 +1,70 @@
# Generated by Django 3.2.12 on 2022-06-27 00:36
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('hrm', '0002_auto_20220617_1124'),
('system', '0005_auto_20220627_0836'),
('am', '0005_auto_20220625_1631'),
]
operations = [
migrations.RemoveField(
model_name='access',
name='obj',
),
migrations.AddField(
model_name='access',
name='dept',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='system.dept', verbose_name='关联部门'),
),
migrations.AddField(
model_name='access',
name='employee',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='hrm.employee', verbose_name='关联人员'),
),
migrations.AddField(
model_name='access',
name='post',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='system.post', verbose_name='关联岗位'),
),
migrations.AddField(
model_name='access',
name='sort',
field=models.PositiveSmallIntegerField(default=1, verbose_name='排序'),
),
migrations.AddField(
model_name='access',
name='stay_minute_max',
field=models.PositiveSmallIntegerField(default=0, verbose_name='最长停留时间'),
),
migrations.AddField(
model_name='access',
name='stay_minute_min',
field=models.PositiveSmallIntegerField(default=0, verbose_name='最短停留时间'),
),
migrations.AddField(
model_name='area',
name='stay_minute_max',
field=models.PositiveSmallIntegerField(default=0, help_text='0代表未配置', verbose_name='最长停留时间'),
),
migrations.AddField(
model_name='area',
name='stay_minute_min',
field=models.PositiveSmallIntegerField(default=0, help_text='0代表未配置', verbose_name='最短停留时间'),
),
migrations.AlterField(
model_name='access',
name='obj_cate',
field=models.CharField(help_text='post/dept/people', max_length=20, verbose_name='对象类型'),
),
migrations.AlterField(
model_name='area',
name='employee_yes',
field=models.BooleanField(default=True, verbose_name='准许内部员工'),
),
]

View File

@ -1,6 +1,6 @@
from django.db import models from django.db import models
from apps.hrm.models import Employee from apps.hrm.models import Employee
from apps.system.models import Post, User from apps.system.models import Dept, Post, User
from apps.utils.constants import ObjCate from apps.utils.constants import ObjCate
from apps.utils.models import CommonADModel, CommonBModel from apps.utils.models import CommonADModel, CommonBModel
# Create your models here. # Create your models here.
@ -33,10 +33,12 @@ class Area(CommonBModel):
number = models.CharField('编号', max_length=20, null=True, blank=True) number = models.CharField('编号', max_length=20, null=True, blank=True)
visitor_yes = models.BooleanField('准许访客人员', default=False) visitor_yes = models.BooleanField('准许访客人员', default=False)
remployee_yes = models.BooleanField('准许相关方人员', default=False) remployee_yes = models.BooleanField('准许相关方人员', default=False)
employee_yes = models.BooleanField('准许部员工', default=True) employee_yes = models.BooleanField('准许部员工', default=True)
count_people_min = models.PositiveIntegerField('最小人员数', default=0) count_people_min = models.PositiveIntegerField('最小人员数', default=0)
count_people_max = models.PositiveIntegerField('最大人员数', default=1000) count_people_max = models.PositiveIntegerField('最大人员数', default=1000)
count_people = models.PositiveIntegerField('当前人数', default=0) count_people = models.PositiveIntegerField('当前人数', default=0)
stay_minute_min = models.PositiveSmallIntegerField('最短停留时间', default=0, help_text='0代表未配置')
stay_minute_max = models.PositiveSmallIntegerField('最长停留时间', default=0, help_text='0代表未配置')
is_hidden = models.BooleanField('隐藏围栏用', default=False) is_hidden = models.BooleanField('隐藏围栏用', default=False)
third_info = models.JSONField('三方信息', default=dict, third_info = models.JSONField('三方信息', default=dict,
null=False, blank=True) null=False, blank=True)
@ -59,6 +61,10 @@ class Access(CommonADModel):
type = models.PositiveSmallIntegerField('准入类型', choices=ACCESS_CHOICE) type = models.PositiveSmallIntegerField('准入类型', choices=ACCESS_CHOICE)
area = models.ForeignKey(Area, verbose_name='关联区域', area = models.ForeignKey(Area, verbose_name='关联区域',
on_delete=models.CASCADE) on_delete=models.CASCADE)
obj_cate = models.CharField('对象类型', max_length=20, help_text='employee/post') obj_cate = models.CharField('对象类型', max_length=20, help_text='post/dept/people')
obj = models.CharField('关联对象', unique=True, max_length=50, null=True, blank=True) post = models.ForeignKey(Post, verbose_name='关联岗位', on_delete=models.CASCADE, null=True, blank=True)
dept = models.ForeignKey(Dept, verbose_name='关联部门', on_delete=models.CASCADE, null=True, blank=True)
employee = models.ForeignKey(Employee, verbose_name='关联人员', on_delete=models.CASCADE, null=True, blank=True)
stay_minute_min = models.PositiveSmallIntegerField('最短停留时间', default=0)
stay_minute_max = models.PositiveSmallIntegerField('最长停留时间', default=0)
sort = models.PositiveSmallIntegerField('排序', default=1) sort = models.PositiveSmallIntegerField('排序', default=1)

View File

@ -3,7 +3,7 @@ from apps.am.models import Access, Area
from apps.hrm.models import Employee from apps.hrm.models import Employee
from apps.system.models import Post from apps.system.models import Post
from apps.utils.serializers import CustomModelSerializer from apps.utils.serializers import CustomModelSerializer
from apps.system.serializers import PostSimpleSerializer from rest_framework.exceptions import ParseError
class AreaSimpleSerializer(CustomModelSerializer): class AreaSimpleSerializer(CustomModelSerializer):
@ -28,7 +28,27 @@ class AreaCreateUpdateSerializer(CustomModelSerializer):
class AccessCreateSerializer(CustomModelSerializer): class AccessCreateSerializer(CustomModelSerializer):
class Meta: class Meta:
model = Access model = Access
fields = ['type', 'area', 'obj_cate', 'obj'] fields = ['type', 'area', 'obj_cate', 'post', 'employee']
def create(self, validated_data):
post = validated_data.get('post', None)
dept = validated_data.get('dept', None)
employee = validated_data.get('employee', None)
if post:
validated_data['obj_cate'] = 'post'
validated_data['employee'] = None
validated_data['dept'] = None
elif dept:
validated_data['obj_cate'] = 'dept'
validated_data['post'] = None
validated_data['employee'] = None
elif employee:
validated_data['obj_cate'] = 'people'
validated_data['post'] = None
validated_data['dept'] = None
else:
raise ParseError('请指定岗位或部门或具体人员')
return super().create(validated_data)
class AccessSerializer(CustomModelSerializer): class AccessSerializer(CustomModelSerializer):

View File

@ -16,6 +16,7 @@ class AreaViewSet(CustomModelViewSet):
create_serializer_class = AreaCreateUpdateSerializer create_serializer_class = AreaCreateUpdateSerializer
update_serializer_class = AreaCreateUpdateSerializer update_serializer_class = AreaCreateUpdateSerializer
serializer_class = AreaSerializer serializer_class = AreaSerializer
ordering = ['number']
@transaction.atomic @transaction.atomic
@action(methods=['post'], detail=True, perms_map={'post': 'area:bind_rail'}, @action(methods=['post'], detail=True, perms_map={'post': 'area:bind_rail'},

View File

@ -34,7 +34,7 @@ class EcmService:
cls.rail_in(data=data.data) cls.rail_in(data=data.data)
elif data.data.type == 2: elif data.data.type == 2:
# 围栏离开 # 围栏离开
pass cls.rail_out(data=data.data)
elif data.type == 'onKeyAlarm': elif data.type == 'onKeyAlarm':
# 一键呼救 # 一键呼救
pass pass
@ -60,44 +60,42 @@ class EcmService:
def rail_in(cls, data): def rail_in(cls, 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 blts and blts.obj_cate == 'employee': # 如果是人 if blts and blts.employee: # 如果是人
if area and area.type == Area.AREA_TYPE_FIX: # 如果是固定区域 ep_blts = blts.employee # 标签绑定人员
json = {"railId": data['railId'], "type": ""}
_, res = xxClient.request(**xxapis['rail_ibeacon_list'], json=json)
total_count = res['totalCount']
if total_count >= area.count_people_max:
# 触发超员事件
area.count_people = total_count
area.save()
pass
elif total_count < area.count_people_min:
# 触发缺员事件
area.count_people_min = total_count
area.save()
pass
ep_blts = Employee.objects.filter(id=blts.obj).first() # 标签绑定人员
if ep_blts: if ep_blts:
# 判断有无进入权限 进行匹配 for i in Access.objects.filter(area=area).order_by('sort'):
# 优先自定义权限过滤
if i.post: # 如果是按岗位设定的
eps_access = Employee.objects.filter(user__posts=i.post)
if ep_blts in eps_access and i.type == Access.ACCESS_IN_YES:
return
elif ep_blts in eps_access and i.type == Access.ACCESS_IN_NO:
# 触发非法进入事件
pass
elif i.employee: # 如果是按人设定的
if ep_blts == i.employee and i.type == Access.ACCESS_IN_YES:
return
elif ep_blts == i.employee and i.type == Access.ACCESS_IN_NO:
# 触发非法进入事件
pass
# 通用权限设置过滤
if ep_blts.type == 'employee' and area.employee_yes: if ep_blts.type == 'employee' and area.employee_yes:
return return
elif ep_blts.type == 'remployee' and area.remployee_yes: elif ep_blts.type == 'remployee' and area.remployee_yes:
return return
elif ep_blts.type == 'visitor' and area.visitor_yes: elif ep_blts.type == 'visitor' and area.visitor_yes:
return return
for i in Access.objects.filter(area=area).order_by('sort'): else:
if i.obj_cate == 'employee': # 触发非法进入事件
ep_acess = Employee.objects.filter(id=i.obj).first() pass
if ep_blts == ep_acess and i.type == 10:
return
elif ep_blts == ep_acess and i.type == 20:
# 触发非法进入事件
pass
elif i.obj_cate == 'post':
pass
else: else:
# 触发未知标签进入事件 # 触发未知标签进入事件
pass pass
@classmethod
def rail_out(cls, data):
pass

View File

@ -0,0 +1,30 @@
from __future__ import absolute_import, unicode_literals
from celery import shared_task
from apps.am.models import Area
from apps.third.clients import xxClient
from apps.third.tapis import xxapis
@shared_task
def cal_area_count():
"""
计算区域内人员数量
"""
for i in Area.objects.filter(type=Area.AREA_TYPE_FIX):
if i.third_info.get('xx_rail', None):
railId = i.third_info['xx_rail']['id']
json = {"railId": railId, "type": ""}
_, res = xxClient.request(**xxapis['rail_ibeacon_list'], json=json)
total_count = res['totalCount']
if total_count >= i.count_people_max:
# 触发超员事件
i.count_people = total_count
i.save()
pass
elif total_count < i.count_people_min:
# 触发缺员事件
i.count_people_min = total_count
i.save()
pass

View File

@ -0,0 +1,30 @@
# Generated by Django 3.2.12 on 2022-06-27 00:36
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('system', '0004_alter_userpost_unique_together'),
]
operations = [
migrations.AlterField(
model_name='userpost',
name='dept',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='up_dept', to='system.dept'),
),
migrations.AlterField(
model_name='userpost',
name='post',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='up_post', to='system.post'),
),
migrations.AlterField(
model_name='userpost',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='up_user', to=settings.AUTH_USER_MODEL),
),
]

View File

@ -147,9 +147,9 @@ class UserPost(BaseModel):
用户岗位关系表 用户岗位关系表
""" """
name = models.CharField('名称', max_length=20, null=True, blank=True) name = models.CharField('名称', max_length=20, null=True, blank=True)
user = models.ForeignKey(User, on_delete=models.CASCADE) user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='up_user')
post = models.ForeignKey(Post, on_delete=models.CASCADE) post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='up_post')
dept = models.ForeignKey(Dept, on_delete=models.CASCADE) dept = models.ForeignKey(Dept, on_delete=models.CASCADE, related_name='up_dept')
sort = models.PositiveSmallIntegerField('排序', default=1) sort = models.PositiveSmallIntegerField('排序', default=1)
class Meta: class Meta:

View File

@ -1,6 +1,7 @@
from django.db import models from django.db import models
from apps.am.models import Area from apps.am.models import Area
import uuid import uuid
from apps.hrm.models import Employee
from apps.utils.constants import ObjCate from apps.utils.constants import ObjCate
from apps.utils.models import BaseModel from apps.utils.models import BaseModel
@ -38,8 +39,8 @@ class TDevice(BaseModel):
verbose_name='所在区', null=True, blank=True) verbose_name='所在区', null=True, blank=True)
areas = models.ManyToManyField(Area, verbose_name='覆盖区', areas = models.ManyToManyField(Area, verbose_name='覆盖区',
related_name='tareas') related_name='tareas')
obj_cate = models.CharField('对象类型', max_length=20, help_text='employee/...') obj_cate = models.CharField('绑定对象', max_length=20, help_text='people/...')
obj = models.CharField('绑定对象', unique=True, max_length=50, null=True, blank=True) employee = models.ForeignKey(Employee, verbose_name='绑定人员', on_delete=models.CASCADE, null=True, blank=True)
is_clock = models.BooleanField('是否打卡设备', default=False) is_clock = models.BooleanField('是否打卡设备', default=False)
third_info = models.JSONField('三方信息', default=dict, third_info = models.JSONField('三方信息', default=dict,
null=False, blank=True) null=False, blank=True)