员工创建与更新与大华联动,通道授权
This commit is contained in:
parent
c400fd79b4
commit
2c2172e990
|
@ -1 +1,4 @@
|
||||||
NO_NEED_LEVEL_REMARK = {"code":"no_need_level_remark", "detail":"无需填写离岗说明"}
|
NO_NEED_LEVEL_REMARK = {"code":"no_need_level_remark", "detail":"无需填写离岗说明"}
|
||||||
|
PHONE_F_WRONG = {"code":"phone_f_wrong", "detail":"手机号格式错误"}
|
||||||
|
PHONE_EXIST = {"code":"phone_exist", "detail":"手机号已存在"}
|
||||||
|
DH_PHOTO_FALI = {"code":"dh_photo_fail", "detail":"大华照片人脸提取失败"}
|
|
@ -1,4 +1,4 @@
|
||||||
# Generated by Django 3.2.6 on 2021-08-13 09:16
|
# Generated by Django 3.2.12 on 2022-04-13 06:34
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
@ -11,29 +11,75 @@ class Migration(migrations.Migration):
|
||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
('system', '0003_remove_user_phone'),
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Employee',
|
name='NotWorkRemark',
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.CharField(editable=False, help_text='主键ID', max_length=20, primary_key=True, serialize=False, verbose_name='主键ID')),
|
||||||
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
|
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
|
||||||
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
|
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
|
||||||
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
|
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
|
||||||
('number', models.CharField(blank=True, max_length=50, null=True, unique=True, verbose_name='人员编号')),
|
('not_work_date', models.DateField(verbose_name='未打卡日期')),
|
||||||
|
('remark', models.CharField(blank=True, max_length=200, null=True, verbose_name='未打卡说明')),
|
||||||
|
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='notworkremark_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
||||||
|
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='notworkremark_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||||
|
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='用户')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Employee',
|
||||||
|
fields=[
|
||||||
|
('id', models.CharField(editable=False, help_text='主键ID', max_length=20, primary_key=True, serialize=False, verbose_name='主键ID')),
|
||||||
|
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
|
||||||
|
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
|
||||||
|
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
|
||||||
|
('name', models.CharField(max_length=20, verbose_name='姓名')),
|
||||||
|
('phone', models.CharField(blank=True, max_length=11, null=True, verbose_name='手机号')),
|
||||||
|
('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='邮箱号')),
|
||||||
|
('number', models.CharField(blank=True, max_length=50, null=True, verbose_name='人员编号')),
|
||||||
('photo', models.CharField(blank=True, max_length=1000, null=True, verbose_name='证件照')),
|
('photo', models.CharField(blank=True, max_length=1000, null=True, verbose_name='证件照')),
|
||||||
('ID_number', models.CharField(blank=True, max_length=100, null=True, verbose_name='身份证号')),
|
('id_number', models.CharField(blank=True, max_length=100, null=True, verbose_name='身份证号')),
|
||||||
('gender', models.CharField(default='男', max_length=10, verbose_name='性别')),
|
('gender', models.CharField(default='男', max_length=10, verbose_name='性别')),
|
||||||
('signature', models.CharField(blank=True, max_length=200, null=True, verbose_name='签名图片')),
|
('signature', models.CharField(blank=True, max_length=200, null=True, verbose_name='签名图片')),
|
||||||
|
('birthday', models.DateField(blank=True, null=True, verbose_name='出生年月日')),
|
||||||
|
('qualification', models.CharField(blank=True, max_length=50, null=True, verbose_name='学历')),
|
||||||
|
('job_state', models.IntegerField(choices=[(10, '在职'), (20, '离职')], default=1, verbose_name='在职状态')),
|
||||||
|
('face_data', models.JSONField(blank=True, null=True, verbose_name='人脸识别数据')),
|
||||||
|
('is_atwork', models.BooleanField(default=False, verbose_name='当前在岗')),
|
||||||
|
('show_atwork', models.BooleanField(default=True, verbose_name='是否展示在岗状态')),
|
||||||
|
('last_check_time', models.DateTimeField(blank=True, null=True, verbose_name='打卡时间')),
|
||||||
|
('not_work_remark', models.CharField(blank=True, max_length=200, null=True, verbose_name='当前未打卡说明')),
|
||||||
|
('third_info', models.JSONField(blank=True, default=dict, null=True, verbose_name='三方信息')),
|
||||||
|
('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='employee_belong_dept', to='system.dept', verbose_name='所属部门')),
|
||||||
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='employee_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='employee_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
||||||
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='employee_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='employee_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='employee_user', to=settings.AUTH_USER_MODEL)),
|
('user', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='employee_user', to=settings.AUTH_USER_MODEL, verbose_name='系统账号')),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'verbose_name': '员工补充信息',
|
'verbose_name': '员工补充信息',
|
||||||
'verbose_name_plural': '员工补充信息',
|
'verbose_name_plural': '员工补充信息',
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='ClockRecord',
|
||||||
|
fields=[
|
||||||
|
('id', models.CharField(editable=False, help_text='主键ID', max_length=20, primary_key=True, serialize=False, verbose_name='主键ID')),
|
||||||
|
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
|
||||||
|
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
|
||||||
|
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
|
||||||
|
('type', models.PositiveSmallIntegerField(choices=[(10, '上班打卡')], default=10, verbose_name='打卡类型')),
|
||||||
|
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='clockrecord_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
||||||
|
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='clockrecord_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
# Generated by Django 3.2.6 on 2021-09-24 03:27
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('system', '0003_auto_20210812_0909'),
|
|
||||||
('hrm', '0001_initial'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='employee',
|
|
||||||
name='academic',
|
|
||||||
field=models.CharField(blank=True, max_length=50, null=True, verbose_name='学历'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='employee',
|
|
||||||
name='birthdate',
|
|
||||||
field=models.DateField(blank=True, null=True, verbose_name='出生年月'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='employee',
|
|
||||||
name='job',
|
|
||||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='system.position', verbose_name='岗位'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='employee',
|
|
||||||
name='jobstate',
|
|
||||||
field=models.IntegerField(choices=[(1, '在职'), (2, '离职')], default=1, verbose_name='在职状态'),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,18 +0,0 @@
|
||||||
# Generated by Django 3.2.6 on 2021-10-18 05:26
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('hrm', '0002_auto_20210924_1127'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='employee',
|
|
||||||
name='face_data',
|
|
||||||
field=models.JSONField(blank=True, null=True, verbose_name='人脸识别数据'),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,32 +0,0 @@
|
||||||
# Generated by Django 3.2.9 on 2022-01-21 06:45
|
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
import django.utils.timezone
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
||||||
('hrm', '0003_employee_face_data'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='ClockRecord',
|
|
||||||
fields=[
|
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
|
|
||||||
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
|
|
||||||
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
|
|
||||||
('type', models.PositiveSmallIntegerField(choices=[(10, '上班打卡')], default=10, verbose_name='打卡类型')),
|
|
||||||
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='clockrecord_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
|
||||||
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='clockrecord_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'abstract': False,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,37 +0,0 @@
|
||||||
# Generated by Django 3.2.9 on 2022-01-26 05:51
|
|
||||||
|
|
||||||
from django.db import migrations
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('hrm', '0004_clockrecord'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.RenameField(
|
|
||||||
model_name='employee',
|
|
||||||
old_name='birthdate',
|
|
||||||
new_name='birthday',
|
|
||||||
),
|
|
||||||
migrations.RenameField(
|
|
||||||
model_name='employee',
|
|
||||||
old_name='ID_number',
|
|
||||||
new_name='id_number',
|
|
||||||
),
|
|
||||||
migrations.RenameField(
|
|
||||||
model_name='employee',
|
|
||||||
old_name='jobstate',
|
|
||||||
new_name='job_state',
|
|
||||||
),
|
|
||||||
migrations.RenameField(
|
|
||||||
model_name='employee',
|
|
||||||
old_name='academic',
|
|
||||||
new_name='qualification',
|
|
||||||
),
|
|
||||||
migrations.RemoveField(
|
|
||||||
model_name='employee',
|
|
||||||
name='job',
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,23 +0,0 @@
|
||||||
# Generated by Django 3.2.9 on 2022-02-17 13:55
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('hrm', '0005_auto_20220126_1351'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='employee',
|
|
||||||
name='is_atwork',
|
|
||||||
field=models.BooleanField(default=False, verbose_name='当前在岗'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='employee',
|
|
||||||
name='last_check_time',
|
|
||||||
field=models.DateTimeField(blank=True, null=True, verbose_name='打卡时间'),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,41 +0,0 @@
|
||||||
# Generated by Django 3.2.9 on 2022-02-18 00:43
|
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
import django.utils.timezone
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
||||||
('hrm', '0006_auto_20220217_2155'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='employee',
|
|
||||||
name='not_work_remark',
|
|
||||||
field=models.CharField(blank=True, max_length=200, null=True, verbose_name='当前未打卡说明'),
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='NotWorkRemark',
|
|
||||||
fields=[
|
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
|
|
||||||
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
|
|
||||||
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
|
|
||||||
('year', models.PositiveSmallIntegerField(default=2022, verbose_name='年')),
|
|
||||||
('month', models.PositiveSmallIntegerField(default=2, verbose_name='月')),
|
|
||||||
('day', models.PositiveSmallIntegerField(default=1, verbose_name='日')),
|
|
||||||
('remark', models.CharField(blank=True, max_length=200, null=True, verbose_name='未打卡说明')),
|
|
||||||
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='notworkremark_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
|
||||||
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='notworkremark_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
|
||||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='用户')),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'abstract': False,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,32 +0,0 @@
|
||||||
# Generated by Django 3.2.9 on 2022-02-22 03:12
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.utils.timezone
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('hrm', '0007_auto_20220218_0843'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.RemoveField(
|
|
||||||
model_name='notworkremark',
|
|
||||||
name='day',
|
|
||||||
),
|
|
||||||
migrations.RemoveField(
|
|
||||||
model_name='notworkremark',
|
|
||||||
name='month',
|
|
||||||
),
|
|
||||||
migrations.RemoveField(
|
|
||||||
model_name='notworkremark',
|
|
||||||
name='year',
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='notworkremark',
|
|
||||||
name='not_work_date',
|
|
||||||
field=models.DateField(default=django.utils.timezone.now, verbose_name='未打卡日期'),
|
|
||||||
preserve_default=False,
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,18 +0,0 @@
|
||||||
# Generated by Django 3.2.9 on 2022-03-17 03:57
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('hrm', '0008_auto_20220222_1112'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='employee',
|
|
||||||
name='show_atwork',
|
|
||||||
field=models.BooleanField(default=True, verbose_name='是否展示在岗状态'),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -36,7 +36,7 @@ class Employee(CommonBModel):
|
||||||
show_atwork = models.BooleanField('是否展示在岗状态', default=True)
|
show_atwork = models.BooleanField('是否展示在岗状态', default=True)
|
||||||
last_check_time = models.DateTimeField('打卡时间', null=True, blank=True)
|
last_check_time = models.DateTimeField('打卡时间', null=True, blank=True)
|
||||||
not_work_remark = models.CharField('当前未打卡说明', null=True, blank=True, max_length=200)
|
not_work_remark = models.CharField('当前未打卡说明', null=True, blank=True, max_length=200)
|
||||||
|
third_info = models.JSONField('三方信息', default=dict, null=True, blank=True)
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = '员工补充信息'
|
verbose_name = '员工补充信息'
|
||||||
verbose_name_plural = verbose_name
|
verbose_name_plural = verbose_name
|
||||||
|
@ -44,6 +44,15 @@ class Employee(CommonBModel):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
# class Card(CommonAModel):
|
||||||
|
# """
|
||||||
|
# 卡
|
||||||
|
# """
|
||||||
|
# CARD_FACE = 10
|
||||||
|
# CARD_LOCATION = 20
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class NotWorkRemark(CommonAModel):
|
class NotWorkRemark(CommonAModel):
|
||||||
"""
|
"""
|
||||||
离岗说明
|
离岗说明
|
||||||
|
|
|
@ -1,18 +1,22 @@
|
||||||
from apps.system.models import User
|
from apps.hrm.errors import DH_PHOTO_FALI, PHONE_EXIST, PHONE_F_WRONG
|
||||||
|
from apps.system.models import Dept, User
|
||||||
from rest_framework.serializers import ModelSerializer
|
from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from apps.utils.serializers import CustomModelSerializer
|
from apps.utils.serializers import CustomModelSerializer
|
||||||
from apps.utils.constants import EXCLUDE_FIELDS
|
from apps.utils.constants import EXCLUDE_FIELDS
|
||||||
|
from apps.utils.tools import rannum, ranstr
|
||||||
from .models import ClockRecord, Employee, NotWorkRemark
|
from .models import ClockRecord, Employee, NotWorkRemark
|
||||||
from apps.system.serializers import DeptSimpleSerializer,UserSimpleSerializer
|
from apps.system.serializers import DeptSimpleSerializer,UserSimpleSerializer
|
||||||
|
from django.db import transaction
|
||||||
|
from apps.utils.dahua import dhClient
|
||||||
|
from apps.third.tapis import dhapis
|
||||||
|
import re
|
||||||
|
from server.settings import DEBUG
|
||||||
|
from rest_framework.exceptions import ParseError
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
class EmployeeSerializer(CustomModelSerializer):
|
class EmployeeBaseSerializer(CustomModelSerializer):
|
||||||
belong_dept_ = DeptSimpleSerializer(source='user.belong_dept', read_only=True)
|
|
||||||
class Meta:
|
|
||||||
model = Employee
|
|
||||||
exclude = EXCLUDE_FIELDS + ['face_data']
|
|
||||||
|
|
||||||
def save(self, **kwargs):
|
def save(self, **kwargs):
|
||||||
if self.validated_data.get('user', None):
|
if self.validated_data.get('user', None):
|
||||||
user = self.validated_data['user']
|
user = self.validated_data['user']
|
||||||
|
@ -21,6 +25,174 @@ class EmployeeSerializer(CustomModelSerializer):
|
||||||
return super().save(**kwargs)
|
return super().save(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def phone_check(phone):
|
||||||
|
re_phone = '^1[358]\d{9}$|^147\d{8}$|^176\d{8}$'
|
||||||
|
if not re.match(re_phone, phone):
|
||||||
|
raise serializers.ValidationError(**PHONE_F_WRONG)
|
||||||
|
return phone
|
||||||
|
|
||||||
|
class EmployeeCreateUpdateSerializer(EmployeeBaseSerializer):
|
||||||
|
phone = serializers.CharField(label="手机号", validators=[phone_check])
|
||||||
|
class Meta:
|
||||||
|
model = Employee
|
||||||
|
exclude = EXCLUDE_FIELDS + ['face_data',
|
||||||
|
'is_atwork', 'last_check_time',
|
||||||
|
'not_work_remark', 'third_info']
|
||||||
|
extra_kwargs = {
|
||||||
|
'phone': {'required': True},
|
||||||
|
'number': {'required': True},
|
||||||
|
'photo': {'required': True},
|
||||||
|
'id_number': {'required': True},
|
||||||
|
}
|
||||||
|
|
||||||
|
@transaction.atomic
|
||||||
|
def create(self, validated_data):
|
||||||
|
instance = super().create(validated_data)
|
||||||
|
if dhClient:
|
||||||
|
# 创建人员
|
||||||
|
_, res = dhClient.request(**dhapis['gen_person_id'])
|
||||||
|
personId = res['id']
|
||||||
|
departmentId = 1
|
||||||
|
if instance.belong_dept:
|
||||||
|
try:
|
||||||
|
departmentId = instance.belong_dept.third_info['dh_id']
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
json_data = {
|
||||||
|
"service":"ehs",
|
||||||
|
"id": personId,
|
||||||
|
"name": instance.name,
|
||||||
|
"code": instance.number,
|
||||||
|
"paperType": 111,
|
||||||
|
"paperNumber": instance.id_number,
|
||||||
|
"paperAddress": "default",
|
||||||
|
"departmentId": departmentId,
|
||||||
|
"phone": instance.phone,
|
||||||
|
"email": instance.email,
|
||||||
|
"sex": 1 if instance.gender == '男' else 2
|
||||||
|
}
|
||||||
|
_, res = dhClient.request(**dhapis['person_img_upload'], file_path_rela=instance.photo)
|
||||||
|
dh_photo = res["fileUrl"]
|
||||||
|
json_data.update(
|
||||||
|
{
|
||||||
|
"biosignatureTypeList":[3],
|
||||||
|
"personBiosignatures":[{
|
||||||
|
"type":3,
|
||||||
|
"index":1,
|
||||||
|
"path": dh_photo
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
_, res = dhClient.request(**dhapis['person_add'], json=json_data)
|
||||||
|
# 开人脸卡
|
||||||
|
_, res = dhClient.request(**dhapis['gen_card_id'])
|
||||||
|
cardId = res['id']
|
||||||
|
cardNumber = instance.id[:8] + rannum(2)
|
||||||
|
now = datetime.now()
|
||||||
|
startDate = now.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
endDate = (datetime(year=now.year+50,
|
||||||
|
month=now.month, day=1)).strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
json_data = {
|
||||||
|
"id": cardId,
|
||||||
|
"cardNumber": cardNumber,
|
||||||
|
"category": 0,
|
||||||
|
"cardType": 0,
|
||||||
|
"personId": personId,
|
||||||
|
"departmentId":departmentId,
|
||||||
|
"startDate": startDate,
|
||||||
|
"endDate": endDate
|
||||||
|
}
|
||||||
|
_, res = dhClient.request(**dhapis['card_add'], json=json_data)
|
||||||
|
instance.third_info = {'dh_id':personId,
|
||||||
|
'dh_photo':dh_photo, 'dh_face_card':res['id']}
|
||||||
|
instance.save()
|
||||||
|
return instance
|
||||||
|
|
||||||
|
@transaction.atomic
|
||||||
|
def update(self, instance, validated_data):
|
||||||
|
old_photo = instance.photo
|
||||||
|
instance = super().update(instance, validated_data)
|
||||||
|
departmentId = 1
|
||||||
|
if instance.belong_dept:
|
||||||
|
try:
|
||||||
|
departmentId = instance.belong_dept.third_info['dh_id']
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
if dhClient:
|
||||||
|
third_info = instance.third_info
|
||||||
|
dh_id = instance.third_info['dh_id']
|
||||||
|
dh_photo = third_info['dh_photo']
|
||||||
|
json_data = {
|
||||||
|
"service":"ehs",
|
||||||
|
"id": dh_id,
|
||||||
|
"name": instance.name,
|
||||||
|
"code": instance.number,
|
||||||
|
"paperType": 111,
|
||||||
|
"paperNumber": instance.id_number,
|
||||||
|
"paperAddress": "default",
|
||||||
|
"departmentId": departmentId,
|
||||||
|
"phone": instance.phone,
|
||||||
|
"email": instance.email,
|
||||||
|
"sex": 1 if instance.gender == '男' else 2,
|
||||||
|
"biosignatureTypeList":[3],
|
||||||
|
"personBiosignatures":[{
|
||||||
|
"type":3,
|
||||||
|
"index":1,
|
||||||
|
"path": third_info['dh_photo']
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
if instance.photo != old_photo:
|
||||||
|
_, res = dhClient.request(**dhapis['person_img_upload'], file_path_rela=instance.photo)
|
||||||
|
dh_photo = res["fileUrl"]
|
||||||
|
json_data.update(
|
||||||
|
{
|
||||||
|
"biosignatureTypeList":[3],
|
||||||
|
"personBiosignatures":[{
|
||||||
|
"type":3,
|
||||||
|
"index":1,
|
||||||
|
"path": dh_photo
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
third_info['dh_photo'] = dh_photo
|
||||||
|
dhClient.request(**dhapis['person_update'], json=json_data)
|
||||||
|
# 开人脸卡
|
||||||
|
if instance.job_state in [Employee.JOB_ON]:
|
||||||
|
if not third_info.get('dh_face_card', None):
|
||||||
|
_, res = dhClient.request(**dhapis['gen_card_id'])
|
||||||
|
cardId = res['id']
|
||||||
|
cardNumber = instance.id[:8] + rannum(2)
|
||||||
|
now = datetime.now()
|
||||||
|
startDate = now.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
endDate = (datetime(year=now.year+50,
|
||||||
|
month=now.month, day=1)).strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
json_data = {
|
||||||
|
"id": cardId,
|
||||||
|
"cardNumber": cardNumber,
|
||||||
|
"category": 0,
|
||||||
|
"cardType": 0,
|
||||||
|
"personId": third_info['dh_id'],
|
||||||
|
"departmentId":departmentId,
|
||||||
|
"startDate": startDate,
|
||||||
|
"endDate": endDate
|
||||||
|
}
|
||||||
|
_, res = dhClient.request(**dhapis['card_add'], json=json_data)
|
||||||
|
third_info['dh_face_card'] = cardNumber
|
||||||
|
instance.save()
|
||||||
|
return instance
|
||||||
|
|
||||||
|
class ChannelAuthoritySerializer(serializers.Serializer):
|
||||||
|
pks = serializers.ListField(child=serializers.CharField(max_length=20), label="员工ID列表")
|
||||||
|
channels = serializers.ListField(child=serializers.CharField(max_length=20), label="门通道ID列表")
|
||||||
|
|
||||||
|
class EmployeeSerializer(EmployeeBaseSerializer):
|
||||||
|
belong_dept_ = DeptSimpleSerializer(source='belong_dept', read_only=True)
|
||||||
|
class Meta:
|
||||||
|
model = Employee
|
||||||
|
exclude = ['face_data']
|
||||||
|
read_only_fields = ['is_atwork', 'last_check_time', 'not_work_remark']
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class EmployeeNotWorkRemarkSerializer(ModelSerializer):
|
class EmployeeNotWorkRemarkSerializer(ModelSerializer):
|
||||||
|
|
|
@ -4,7 +4,13 @@ from django.dispatch import receiver
|
||||||
from apps.hrm.models import Employee
|
from apps.hrm.models import Employee
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
# @receiver(post_save, sender=User)
|
@receiver(post_save, sender=User)
|
||||||
# def createEmployee(sender, instance, created, **kwargs):
|
def updateEmployee(sender, instance, created, **kwargs):
|
||||||
# if created:
|
# if created:
|
||||||
# Employee.objects.get_or_create(user=instance)
|
# 如果账号所属部门有变动, 更新关联人员的所属部门
|
||||||
|
ep = Employee.objects.filter(user=instance).first()
|
||||||
|
if ep:
|
||||||
|
if ep.belong_dept and ep.belong_dept != instance.belong_dept:
|
||||||
|
ep.belong_dept = instance.belong_dept
|
||||||
|
ep.save()
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
|
|
||||||
from rest_framework import urlpatterns
|
from rest_framework import urlpatterns
|
||||||
from apps.hrm.views import ClockRecordViewSet, EmployeeViewSet, FaceLogin, NotWorkRemarkViewSet
|
from apps.hrm.views import ClockRecordViewSet, EmployeeViewSet, NotWorkRemarkViewSet
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from rest_framework.routers import DefaultRouter
|
from rest_framework.routers import DefaultRouter
|
||||||
|
|
||||||
|
API_BASE_URL = 'api/hrm/'
|
||||||
|
HTML_BASE_URL = 'hrm/'
|
||||||
|
|
||||||
router = DefaultRouter()
|
router = DefaultRouter()
|
||||||
router.register('employee', EmployeeViewSet, basename='employee')
|
router.register('employee', EmployeeViewSet, basename='employee')
|
||||||
router.register('clock_record', ClockRecordViewSet, basename='clock_record')
|
router.register('clock_record', ClockRecordViewSet, basename='clock_record')
|
||||||
router.register('not_work_remark', NotWorkRemarkViewSet, basename='not_work_reamrk')
|
router.register('not_work_remark', NotWorkRemarkViewSet, basename='not_work_reamrk')
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('facelogin/', FaceLogin.as_view()),
|
path(API_BASE_URL, include(router.urls)),
|
||||||
path('', include(router.urls)),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ from rest_framework.mixins import UpdateModelMixin, RetrieveModelMixin, CreateMo
|
||||||
from apps.hrm.errors import NO_NEED_LEVEL_REMARK
|
from apps.hrm.errors import NO_NEED_LEVEL_REMARK
|
||||||
from apps.hrm.filters import ClockRecordFilterSet, EmployeeFilterSet, NotWorkRemarkFilterSet
|
from apps.hrm.filters import ClockRecordFilterSet, EmployeeFilterSet, NotWorkRemarkFilterSet
|
||||||
from apps.hrm.models import ClockRecord, Employee, NotWorkRemark
|
from apps.hrm.models import ClockRecord, Employee, NotWorkRemark
|
||||||
from apps.hrm.serializers import ClockRecordListSerializer, EmployeeNotWorkRemarkSerializer, EmployeeSerializer, FaceClockCreateSerializer, FaceLoginSerializer, NotWorkRemarkListSerializer
|
from apps.hrm.serializers import ClockRecordListSerializer, ChannelAuthoritySerializer, EmployeeCreateUpdateSerializer, EmployeeNotWorkRemarkSerializer, EmployeeSerializer, NotWorkRemarkListSerializer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,9 +17,14 @@ from apps.system.models import User
|
||||||
from apps.system.serializers import UserSimpleSerializer
|
from apps.system.serializers import UserSimpleSerializer
|
||||||
from rest_framework.permissions import AllowAny
|
from rest_framework.permissions import AllowAny
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
|
from apps.utils.serializers import PkSerializer
|
||||||
from apps.utils.viewsets import CustomModelViewSet, CustomGenericViewSet
|
from apps.utils.viewsets import CustomModelViewSet, CustomGenericViewSet
|
||||||
from rest_framework.exceptions import ParseError
|
from rest_framework.exceptions import ParseError
|
||||||
|
from django.db import transaction
|
||||||
|
from datetime import datetime
|
||||||
|
from rest_framework import serializers
|
||||||
|
from apps.utils.dahua import dhClient
|
||||||
|
from apps.third.tapis import dhapis
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
class EmployeeViewSet(CustomModelViewSet):
|
class EmployeeViewSet(CustomModelViewSet):
|
||||||
|
@ -30,22 +35,12 @@ class EmployeeViewSet(CustomModelViewSet):
|
||||||
select_related_fields = ['user']
|
select_related_fields = ['user']
|
||||||
filterset_class = EmployeeFilterSet
|
filterset_class = EmployeeFilterSet
|
||||||
serializer_class = EmployeeSerializer
|
serializer_class = EmployeeSerializer
|
||||||
|
create_serializer_class = EmployeeCreateUpdateSerializer
|
||||||
|
update_serializer_class = EmployeeCreateUpdateSerializer
|
||||||
|
partial_update_serializer_class = EmployeeCreateUpdateSerializer
|
||||||
search_fields = ['name', 'number', 'user__username']
|
search_fields = ['name', 'number', 'user__username']
|
||||||
ordering = ['-pk']
|
ordering = ['-pk']
|
||||||
|
|
||||||
def update(self, request, *args, **kwargs):
|
|
||||||
partial = kwargs.pop('partial', False)
|
|
||||||
instance = self.get_object()
|
|
||||||
data = request.data
|
|
||||||
serializer = self.get_serializer(instance, data=data, partial=partial)
|
|
||||||
serializer.is_valid(raise_exception=True)
|
|
||||||
photo = data.get('photo', None)
|
|
||||||
if instance.photo != photo:
|
|
||||||
# 调取大华接口
|
|
||||||
return Response()
|
|
||||||
serializer.save()
|
|
||||||
return Response()
|
|
||||||
|
|
||||||
@action(methods=['post'], detail=True, perms_map={'post': 'employee_notworkremark'}
|
@action(methods=['post'], detail=True, perms_map={'post': 'employee_notworkremark'}
|
||||||
, serializer_class=EmployeeNotWorkRemarkSerializer)
|
, serializer_class=EmployeeNotWorkRemarkSerializer)
|
||||||
def not_work_remark(self, request, pk=None):
|
def not_work_remark(self, request, pk=None):
|
||||||
|
@ -77,6 +72,37 @@ class EmployeeViewSet(CustomModelViewSet):
|
||||||
return Response()
|
return Response()
|
||||||
raise ParseError(**NO_NEED_LEVEL_REMARK)
|
raise ParseError(**NO_NEED_LEVEL_REMARK)
|
||||||
|
|
||||||
|
@transaction.atomic
|
||||||
|
@action(methods=['post'], detail=False, perms_map={'post': 'employee_channel_authority'}
|
||||||
|
, serializer_class=ChannelAuthoritySerializer)
|
||||||
|
def channel_authority(self, request, pk=None):
|
||||||
|
"""门通道授权
|
||||||
|
|
||||||
|
门通道授权
|
||||||
|
"""
|
||||||
|
serializer = self.get_serializer(data=request.data)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
vdata = serializer.validated_data
|
||||||
|
objs = Employee.objects.filter(pk__in=vdata['pks'])
|
||||||
|
infos = objs.values('third_info')
|
||||||
|
cards = []
|
||||||
|
for i in infos:
|
||||||
|
if isinstance(i['third_info'], dict) and 'dh_face_card' in i['third_info']:
|
||||||
|
cards.append(i['third_info']['dh_face_card'])
|
||||||
|
details = []
|
||||||
|
for i in vdata['channels']:
|
||||||
|
details.append({
|
||||||
|
"privilegeType": 1,
|
||||||
|
"resouceCode": i
|
||||||
|
})
|
||||||
|
json_data = {
|
||||||
|
"cardNumbers": cards,
|
||||||
|
"timeQuantumId": 1,
|
||||||
|
"cardPrivilegeDetails": details
|
||||||
|
}
|
||||||
|
dhClient.request(**dhapis['card_door_authority'], json=json_data)
|
||||||
|
objs.update(third_info__dh_channels = vdata['channels'])
|
||||||
|
return Response()
|
||||||
|
|
||||||
class ClockRecordViewSet(ListModelMixin, CustomGenericViewSet):
|
class ClockRecordViewSet(ListModelMixin, CustomGenericViewSet):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 3.2.12 on 2022-04-18 02:36
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('monitor', '0002_alter_drfrequestlog_id'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='drfrequestlog',
|
||||||
|
name='view_method',
|
||||||
|
field=models.CharField(blank=True, db_index=True, max_length=20, null=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -28,7 +28,7 @@ class DrfRequestLog(BaseModel):
|
||||||
help_text="执行视图",
|
help_text="执行视图",
|
||||||
)
|
)
|
||||||
view_method = models.CharField(
|
view_method = models.CharField(
|
||||||
max_length=6,
|
max_length=20,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
db_index=True,
|
db_index=True,
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
SCHEDULE_WRONG = {"code":"schedule_wrong", "detail":"时间策略有误"}
|
SCHEDULE_WRONG = {"code":"schedule_wrong", "detail":"时间策略有误"}
|
||||||
PASSWORD_NOT_SAME = {"code":"password_not_same", "detail":"新旧密码不一致"}
|
PASSWORD_NOT_SAME = {"code":"password_not_same", "detail":"新旧密码不一致"}
|
||||||
OLD_PASSWORD_WRONG = {"code":"old_password_wrong", "detail":"旧密码错误"}
|
OLD_PASSWORD_WRONG = {"code":"old_password_wrong", "detail":"旧密码错误"}
|
||||||
PHONE_F_WRONG = {"code":"phone_f_wrong", "detail":"手机号格式错误"}
|
|
||||||
PHONE_EXIST = {"code":"phone_exist", "detail":"手机号已存在"}
|
|
||||||
USERNAME_EXIST = {"code":"username_exist", "detail":"账户已存在"}
|
USERNAME_EXIST = {"code":"username_exist", "detail":"账户已存在"}
|
||||||
ROLE_NAME_EXIST = {"code":"role_name_exist", "detail":"角色名已存在"}
|
ROLE_NAME_EXIST = {"code":"role_name_exist", "detail":"角色名已存在"}
|
||||||
ROLE_CODE_EXIST = {"code":"role_code_exist", "detail":"角色标识已存在"}
|
ROLE_CODE_EXIST = {"code":"role_code_exist", "detail":"角色标识已存在"}
|
|
@ -3,7 +3,7 @@ import re
|
||||||
from django_celery_beat.models import PeriodicTask, CrontabSchedule, IntervalSchedule
|
from django_celery_beat.models import PeriodicTask, CrontabSchedule, IntervalSchedule
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from django_celery_results.models import TaskResult
|
from django_celery_results.models import TaskResult
|
||||||
from apps.system.errors import PHONE_EXIST, PHONE_F_WRONG, ROLE_CODE_EXIST, ROLE_NAME_EXIST, USERNAME_EXIST
|
from apps.system.errors import ROLE_CODE_EXIST, ROLE_NAME_EXIST, USERNAME_EXIST
|
||||||
from apps.utils.serializers import CustomModelSerializer
|
from apps.utils.serializers import CustomModelSerializer
|
||||||
from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE
|
from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE
|
||||||
from .models import (Dict, DictType, File, Dept, Permission, Post,
|
from .models import (Dict, DictType, File, Dept, Permission, Post,
|
||||||
|
@ -210,8 +210,20 @@ class DeptCreateUpdateSerializer(CustomModelSerializer):
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def update(self, instance, validated_data):
|
def update(self, instance, validated_data):
|
||||||
if instance.name != validated_data.get('name', ''):
|
|
||||||
from apps.utils.dahua import dhClient
|
from apps.utils.dahua import dhClient
|
||||||
|
third_info = instance.third_info
|
||||||
|
if dhClient and not third_info.get('dh_id', False):
|
||||||
|
# 如果dh_id 不存在
|
||||||
|
data = {
|
||||||
|
"parentId":1,
|
||||||
|
"name":validated_data['name'],
|
||||||
|
"service":"ehs"
|
||||||
|
}
|
||||||
|
_, res = dhClient.request(**dhapis['dept_create'],json=data)
|
||||||
|
third_info['dh_id'] = res['id']
|
||||||
|
instance.third_info = third_info
|
||||||
|
instance.save()
|
||||||
|
elif instance.name != validated_data.get('name', ''):
|
||||||
if dhClient and instance.third_info.get('dh_id', False):
|
if dhClient and instance.third_info.get('dh_id', False):
|
||||||
data = {
|
data = {
|
||||||
"id":instance.third_info['dh_id'],
|
"id":instance.third_info['dh_id'],
|
||||||
|
|
|
@ -11,7 +11,51 @@ dhapis = {
|
||||||
"dept_update":{
|
"dept_update":{
|
||||||
"url":"/evo-apigw/evo-brm/1.0.0/department/update",
|
"url":"/evo-apigw/evo-brm/1.0.0/department/update",
|
||||||
"method":"put"
|
"method":"put"
|
||||||
}
|
},
|
||||||
|
"gen_person_id":{
|
||||||
|
"url":"/evo-apigw/evo-brm/1.0.0/person/generate-id",
|
||||||
|
"method":"get"
|
||||||
|
},
|
||||||
|
"person_add": {
|
||||||
|
"url":"/evo-apigw/evo-brm/1.2.0/person/subsystem/add",
|
||||||
|
"method":"post"
|
||||||
|
},
|
||||||
|
"person_update": {
|
||||||
|
"url":"/evo-apigw/evo-brm/1.2.0/person/subsystem/update",
|
||||||
|
"method":"put"
|
||||||
|
},
|
||||||
|
"person_img_upload": {
|
||||||
|
"url":"/evo-apigw/evo-brm/1.2.0/person/upload/img",
|
||||||
|
"method":"post"
|
||||||
|
},
|
||||||
|
"person_detail": {
|
||||||
|
"url":"/evo-apigw/evo-brm/1.0.0/person/subsystem/{id}",
|
||||||
|
"method":"get"
|
||||||
|
},
|
||||||
|
"device_list": {
|
||||||
|
"url":"/evo-apigw/evo-brm/1.2.0/device/subsystem/page",
|
||||||
|
"method":"get"
|
||||||
|
},
|
||||||
|
"device_detail": {
|
||||||
|
"url":"/evo-apigw/evo-brm/1.0.0/device/{deviceCode}",
|
||||||
|
"method":"get"
|
||||||
|
},
|
||||||
|
"channel_list": {
|
||||||
|
"url":"/evo-apigw/evo-brm/1.2.0/device/channel/subsystem/page",
|
||||||
|
"method":"post"
|
||||||
|
},
|
||||||
|
"card_add": {
|
||||||
|
"url":"/evo-apigw/evo-brm/1.2.0/card/add",
|
||||||
|
"method":"post"
|
||||||
|
},
|
||||||
|
"gen_card_id": {
|
||||||
|
"url":"/evo-apigw/evo-brm/1.0.0/card/generate-id",
|
||||||
|
"method":"get"
|
||||||
|
},
|
||||||
|
"card_door_authority": {
|
||||||
|
"url":"/evo-apigw/evo-accesscontrol/1.0.0/card/accessControl/doorAuthority",
|
||||||
|
"method":"post"
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
# 寻息API接口
|
# 寻息API接口
|
||||||
|
|
|
@ -3,6 +3,7 @@ from apps.third.tapis import dhapis, xxapis
|
||||||
from apps.third.erros import TAPI_CODE_WRONG
|
from apps.third.erros import TAPI_CODE_WRONG
|
||||||
from apps.utils.dahua import dhClient
|
from apps.utils.dahua import dhClient
|
||||||
from apps.utils.errors import XX_REQUEST_ERROR
|
from apps.utils.errors import XX_REQUEST_ERROR
|
||||||
|
from apps.utils.mixins import MyLoggingMixin
|
||||||
from apps.utils.xunxi import xxClient
|
from apps.utils.xunxi import xxClient
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
|
@ -15,45 +16,19 @@ from apps.third.serializers import RequestCommonSerializer
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
|
||||||
|
|
||||||
class DahuaTestView(APIView):
|
class DahuaTestView(MyLoggingMixin, APIView):
|
||||||
"""
|
"""
|
||||||
大华测试接口
|
大华测试接口
|
||||||
"""
|
"""
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
data = {
|
# file_path_rela = '/media/default/avatar.png'
|
||||||
"data":{
|
# _, res = dhClient.request(**dhapis['person_img_upload'], file_path_rela=file_path_rela)
|
||||||
"channelId": "1001339$1$0$0",
|
_,res = dhClient.request(
|
||||||
"streamType": "1",
|
url='/evo-apigw/evo-brm/1.0.0/person/subsystem/{}'.format(2059335),
|
||||||
"type": "hls"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# ok, res = dhClient.request(
|
|
||||||
# url='/evo-apigw/admin/API/video/stream/realtime', method='post', json=data)
|
|
||||||
ok, res = dhClient.request(url='/evo-apigw/evo-brm/1.2.0/department/tree',
|
|
||||||
method='get')
|
method='get')
|
||||||
# data = {
|
|
||||||
# "pageNum":1,
|
|
||||||
# "pageSize":100,
|
|
||||||
# "isOnline":1,
|
|
||||||
# "showChildNodeData":1,
|
|
||||||
# "categorys":[8]
|
|
||||||
|
|
||||||
# }
|
|
||||||
# res = dhClient.request(
|
|
||||||
# url='/evo-apigw/evo-brm/1.0.0/device/subsystem/page', method='post', json=data)
|
|
||||||
# data = {
|
|
||||||
# "channelCodeList": ["1001382$7$0$0"]
|
|
||||||
# }
|
|
||||||
# res = dhClient.request(
|
|
||||||
# url='/evo-apigw/evo-accesscontrol/1.0.0/card/accessControl/channelControl/closeDoor', method='post', json=data)
|
|
||||||
if ok == 'success':
|
|
||||||
return Response(res)
|
return Response(res)
|
||||||
elif ok == 'fail':
|
|
||||||
raise ParseError(**res)
|
|
||||||
else:
|
|
||||||
raise APIException(**res)
|
|
||||||
|
|
||||||
|
|
||||||
class XxTestView(APIView):
|
class XxTestView(APIView):
|
||||||
|
|
|
@ -7,6 +7,7 @@ from server import settings
|
||||||
import json
|
import json
|
||||||
import time
|
import time
|
||||||
from rest_framework.exceptions import APIException, ParseError
|
from rest_framework.exceptions import APIException, ParseError
|
||||||
|
import os
|
||||||
requests.packages.urllib3.disable_warnings()
|
requests.packages.urllib3.disable_warnings()
|
||||||
|
|
||||||
class DhClient:
|
class DhClient:
|
||||||
|
@ -63,21 +64,31 @@ class DhClient:
|
||||||
自定义销毁
|
自定义销毁
|
||||||
"""
|
"""
|
||||||
self.isRuning = False
|
self.isRuning = False
|
||||||
self.t.join()
|
# self.t.join()
|
||||||
|
|
||||||
def request(self, url:str, method:str, params=dict(), json=dict(), timeout=20, raise_exception=True):
|
def request(self, url:str, method:str, params=dict(), json=dict(), timeout=4, file_path_rela=None, raise_exception=True):
|
||||||
if self.isGetingToken:
|
if self.isGetingToken:
|
||||||
req_num = 0
|
req_num = 0
|
||||||
while True:
|
while True:
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
if not self.isGetingToken:
|
if not self.isGetingToken:
|
||||||
self.request(url, method, params, json, timeout)
|
self.request(url, method, params, json, timeout, file_path_rela, raise_exception)
|
||||||
req_num = req_num + 1
|
req_num = req_num + 1
|
||||||
if req_num > 4:
|
if req_num > 4:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
files = None
|
||||||
|
if file_path_rela: # 相对路径
|
||||||
|
files = {'file': open(settings.BASE_DIR + file_path_rela, 'rb')}
|
||||||
|
try:
|
||||||
|
if params:
|
||||||
|
url = url.format(**params)
|
||||||
r = getattr(requests, method)('{}{}'.format(settings.DAHUA_BASE_URL, url)
|
r = getattr(requests, method)('{}{}'.format(settings.DAHUA_BASE_URL, url)
|
||||||
, headers = self.headers, params=params, json=json, verify=False)
|
, headers = self.headers, params=params, json=json, timeout=timeout, files=files, verify=False)
|
||||||
|
except:
|
||||||
|
if raise_exception:
|
||||||
|
raise APIException(**DH_REQUEST_ERROR)
|
||||||
|
return 'error', DH_REQUEST_ERROR
|
||||||
# if settings.DEBUG:
|
# if settings.DEBUG:
|
||||||
# print_roundtrip(r)
|
# print_roundtrip(r)
|
||||||
if r.status_code == 200:
|
if r.status_code == 200:
|
||||||
|
@ -87,7 +98,7 @@ class DhClient:
|
||||||
ret = r.json()
|
ret = r.json()
|
||||||
if ret.get('code') == '27001007':
|
if ret.get('code') == '27001007':
|
||||||
self.get_token() # 重新获取token
|
self.get_token() # 重新获取token
|
||||||
self.request(url, method, params, json, timeout) # 重新请求
|
self.request(url, method, params, json, timeout, file_path_rela, raise_exception)
|
||||||
else:
|
else:
|
||||||
if ret['code'] not in ['0', '100', '00000', '1000', 0, 100, 1000]:
|
if ret['code'] not in ['0', '100', '00000', '1000', 0, 100, 1000]:
|
||||||
detail = '大华错误:' + '{}|{}{}'.format(str(ret['code']), ret.get('errMsg',''), ret.get('desc', ''))
|
detail = '大华错误:' + '{}|{}{}'.format(str(ret['code']), ret.get('errMsg',''), ret.get('desc', ''))
|
||||||
|
|
|
@ -68,7 +68,7 @@ class MyLoggingMixin(object):
|
||||||
CLEANED_SUBSTITUTE = "********************"
|
CLEANED_SUBSTITUTE = "********************"
|
||||||
|
|
||||||
# logging_methods = "__all__"
|
# logging_methods = "__all__"
|
||||||
logging_methods = ['POST', 'PUT', 'DELETE', 'PATCH']
|
logging_methods = '__all__'
|
||||||
sensitive_fields = {}
|
sensitive_fields = {}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -100,6 +100,7 @@ class MyLoggingMixin(object):
|
||||||
|
|
||||||
def handle_exception(self, exc):
|
def handle_exception(self, exc):
|
||||||
response = super().handle_exception(exc)
|
response = super().handle_exception(exc)
|
||||||
|
self.log["errors"] = traceback.format_exc()
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def finalize_response(self, request, response, *args, **kwargs):
|
def finalize_response(self, request, response, *args, **kwargs):
|
||||||
|
@ -230,7 +231,7 @@ class MyLoggingMixin(object):
|
||||||
"""
|
"""
|
||||||
return (
|
return (
|
||||||
self.logging_methods == "__all__" or request.method in self.logging_methods
|
self.logging_methods == "__all__" or request.method in self.logging_methods
|
||||||
)
|
) and (response.status_code not in (401, 403))
|
||||||
|
|
||||||
def _clean_data(self, data):
|
def _clean_data(self, data):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import textwrap
|
import textwrap
|
||||||
import requests
|
import random
|
||||||
|
import string
|
||||||
|
|
||||||
def print_roundtrip(response, *args, **kwargs):
|
def print_roundtrip(response, *args, **kwargs):
|
||||||
format_headers = lambda d: '\n'.join(f'{k}: {v}' for k, v in d.items())
|
format_headers = lambda d: '\n'.join(f'{k}: {v}' for k, v in d.items())
|
||||||
|
@ -20,3 +21,11 @@ def print_roundtrip(response, *args, **kwargs):
|
||||||
reqhdrs=format_headers(response.request.headers),
|
reqhdrs=format_headers(response.request.headers),
|
||||||
reshdrs=format_headers(response.headers),
|
reshdrs=format_headers(response.headers),
|
||||||
))
|
))
|
||||||
|
|
||||||
|
def ranstr(num):
|
||||||
|
salt = ''.join(random.sample(string.ascii_lowercase + string.digits, num))
|
||||||
|
return salt
|
||||||
|
|
||||||
|
def rannum(num):
|
||||||
|
salt = ''.join(random.sample(string.digits, num))
|
||||||
|
return salt
|
|
@ -58,7 +58,7 @@ class XxClient:
|
||||||
self.isRuning = False
|
self.isRuning = False
|
||||||
self.t.join()
|
self.t.join()
|
||||||
|
|
||||||
def request(self, url:str, method:str='post', params=dict(), json=dict(), timeout=20, raise_exception=True):
|
def request(self, url:str, method:str='post', params=dict(), json=dict(), timeout=4, raise_exception=True):
|
||||||
params['accessToken'] = self.token
|
params['accessToken'] = self.token
|
||||||
json['username'] = self.username
|
json['username'] = self.username
|
||||||
json['buildId'] = settings.XX_BUILDID
|
json['buildId'] = settings.XX_BUILDID
|
||||||
|
@ -67,19 +67,19 @@ class XxClient:
|
||||||
while True:
|
while True:
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
if not self.isGetingToken:
|
if not self.isGetingToken:
|
||||||
self.request(url, method, params, json, timeout)
|
self.request(url, method, params, json, timeout, raise_exception)
|
||||||
req_num = req_num + 1
|
req_num = req_num + 1
|
||||||
if req_num > 4:
|
if req_num > 4:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
r = getattr(requests, method)('{}{}'.format(settings.XX_BASE_URL, url)
|
r = getattr(requests, method)('{}{}'.format(settings.XX_BASE_URL, url)
|
||||||
, params=params, json=json, verify=False)
|
, params=params, json=json, timeout=timeout, verify=False)
|
||||||
# if settings.DEBUG:
|
# if settings.DEBUG:
|
||||||
# print_roundtrip(r)
|
# print_roundtrip(r)
|
||||||
ret = r.json()
|
ret = r.json()
|
||||||
if ret.get('errorCode') == '1060000':
|
if ret.get('errorCode') == '1060000':
|
||||||
self.get_token() # 重新获取token
|
self.get_token() # 重新获取token
|
||||||
self.request(url, method, params, json, timeout) # 重新请求
|
self.request(url, method, params, json, timeout, raise_exception) # 重新请求
|
||||||
else:
|
else:
|
||||||
if ret['errorCode'] != 0:
|
if ret['errorCode'] != 0:
|
||||||
err_detail = dict(detail='寻息错误:' + '|'.join(ret['errorMsg']),
|
err_detail = dict(detail='寻息错误:' + '|'.join(ret['errorMsg']),
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 57 KiB |
Binary file not shown.
After Width: | Height: | Size: 154 KiB |
|
@ -52,7 +52,8 @@ INSTALLED_APPS = [
|
||||||
'apps.system',
|
'apps.system',
|
||||||
'apps.auth1',
|
'apps.auth1',
|
||||||
'apps.monitor',
|
'apps.monitor',
|
||||||
'apps.wf'
|
'apps.wf',
|
||||||
|
'apps.hrm'
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
|
|
@ -47,6 +47,7 @@ urlpatterns = [
|
||||||
path('', include('apps.third.urls')),
|
path('', include('apps.third.urls')),
|
||||||
path('', include('apps.utils.urls')),
|
path('', include('apps.utils.urls')),
|
||||||
path('', include('apps.develop.urls')),
|
path('', include('apps.develop.urls')),
|
||||||
|
path('', include('apps.hrm.urls')),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue