区域表修改

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 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.models import CommonADModel, CommonBModel
# Create your models here.
@ -33,10 +33,12 @@ class Area(CommonBModel):
number = models.CharField('编号', max_length=20, null=True, blank=True)
visitor_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_max = models.PositiveIntegerField('最大人员数', default=1000)
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)
third_info = models.JSONField('三方信息', default=dict,
null=False, blank=True)
@ -59,6 +61,10 @@ class Access(CommonADModel):
type = models.PositiveSmallIntegerField('准入类型', choices=ACCESS_CHOICE)
area = models.ForeignKey(Area, verbose_name='关联区域',
on_delete=models.CASCADE)
obj_cate = models.CharField('对象类型', max_length=20, help_text='employee/post')
obj = models.CharField('关联对象', unique=True, max_length=50, null=True, blank=True)
obj_cate = models.CharField('对象类型', max_length=20, help_text='post/dept/people')
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)

View File

@ -3,7 +3,7 @@ from apps.am.models import Access, Area
from apps.hrm.models import Employee
from apps.system.models import Post
from apps.utils.serializers import CustomModelSerializer
from apps.system.serializers import PostSimpleSerializer
from rest_framework.exceptions import ParseError
class AreaSimpleSerializer(CustomModelSerializer):
@ -28,7 +28,27 @@ class AreaCreateUpdateSerializer(CustomModelSerializer):
class AccessCreateSerializer(CustomModelSerializer):
class Meta:
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):

View File

@ -16,6 +16,7 @@ class AreaViewSet(CustomModelViewSet):
create_serializer_class = AreaCreateUpdateSerializer
update_serializer_class = AreaCreateUpdateSerializer
serializer_class = AreaSerializer
ordering = ['number']
@transaction.atomic
@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)
elif data.data.type == 2:
# 围栏离开
pass
cls.rail_out(data=data.data)
elif data.type == 'onKeyAlarm':
# 一键呼救
pass
@ -60,44 +60,42 @@ class EcmService:
def rail_in(cls, data):
"""围栏进入事件
"""
# 判断区域是否超员
# 找到所在围栏
area = Area.objects.filter(third_info__xx_rail__id=data['railId']).first()
# 判断进入对象
# 找到进入对象
blts = TDevice.objects.filter(code=data['userId']).first()
if blts and blts.obj_cate == 'employee': # 如果是人
if area and area.type == Area.AREA_TYPE_FIX: # 如果是固定区域
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 blts and blts.employee: # 如果是人
ep_blts = blts.employee # 标签绑定人员
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:
return
elif ep_blts.type == 'remployee' and area.remployee_yes:
return
elif ep_blts.type == 'visitor' and area.visitor_yes:
return
for i in Access.objects.filter(area=area).order_by('sort'):
if i.obj_cate == 'employee':
ep_acess = Employee.objects.filter(id=i.obj).first()
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:
# 触发非法进入事件
pass
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)
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
dept = models.ForeignKey(Dept, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='up_user')
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='up_post')
dept = models.ForeignKey(Dept, on_delete=models.CASCADE, related_name='up_dept')
sort = models.PositiveSmallIntegerField('排序', default=1)
class Meta:

View File

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