创建用户时默认部门为空
This commit is contained in:
parent
1e81f38343
commit
b4db266dd9
|
@ -0,0 +1 @@
|
|||
NO_NEED_LEVEL_REMARK = {"code":"no_need_level_remark", "detail":"无需填写离岗说明"}
|
|
@ -2,12 +2,12 @@ from django.db import models
|
|||
from django.db.models.query import QuerySet
|
||||
from apps.system.models import User
|
||||
|
||||
from apps.utils.models import CommonADModel, CommonAModel
|
||||
from apps.utils.models import CommonADModel, CommonAModel, CommonBModel
|
||||
|
||||
|
||||
|
||||
|
||||
class Employee(CommonAModel):
|
||||
class Employee(CommonBModel):
|
||||
"""
|
||||
员工信息
|
||||
"""
|
||||
|
@ -28,7 +28,7 @@ class Employee(CommonAModel):
|
|||
id_number = models.CharField('身份证号', max_length=100, null=True, blank=True)
|
||||
gender = models.CharField('性别', max_length=10, default='男')
|
||||
signature = models.CharField('签名图片', max_length=200, null=True, blank=True)
|
||||
birthday = models.DateField('出生年月', null=True, blank=True)
|
||||
birthday = models.DateField('出生年月日', null=True, blank=True)
|
||||
qualification = models.CharField('学历', max_length=50, null=True, blank=True)
|
||||
job_state = models.IntegerField('在职状态', choices=jobstate_choices, default=1)
|
||||
face_data = models.JSONField('人脸识别数据', null=True, blank=True)
|
||||
|
|
|
@ -2,13 +2,13 @@ from apps.system.models import User
|
|||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework import serializers
|
||||
|
||||
from utils.mixins import DynamicFieldsSerializerMixin
|
||||
from .models import ClockRecord, Employee, NotWorkRemark
|
||||
from apps.system.serializers import OrganizationSimpleSerializer, UserSimpleSerializer
|
||||
from apps.utils.serializers import CustomModelSerializer
|
||||
|
||||
class EmployeeSerializer(DynamicFieldsSerializerMixin, ModelSerializer):
|
||||
name = serializers.CharField(source='user.name', read_only=True)
|
||||
dept_ = OrganizationSimpleSerializer(source='user.dept', read_only=True)
|
||||
from .models import ClockRecord, Employee, NotWorkRemark
|
||||
from apps.system.serializers import DeptSimpleSerializer,UserSimpleSerializer
|
||||
|
||||
class EmployeeSerializer(CustomModelSerializer):
|
||||
belong_dept_ = DeptSimpleSerializer(source='user.belong_dept', read_only=True)
|
||||
class Meta:
|
||||
model = Employee
|
||||
exclude = ['face_data']
|
||||
|
@ -18,13 +18,6 @@ class EmployeeNotWorkRemarkSerializer(ModelSerializer):
|
|||
model = Employee
|
||||
fields = ['not_work_remark']
|
||||
|
||||
class FaceLoginSerializer(serializers.Serializer):
|
||||
base64 = serializers.CharField()
|
||||
|
||||
|
||||
class FaceClockCreateSerializer(serializers.Serializer):
|
||||
base64 = serializers.CharField()
|
||||
|
||||
class ClockRecordListSerializer(serializers.ModelSerializer):
|
||||
create_by_ = UserSimpleSerializer(source='create_by', read_only=True)
|
||||
class Meta:
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
from django.conf import settings
|
||||
import uuid
|
||||
import face_recognition
|
||||
import os
|
||||
from apps.hrm.models import Employee
|
||||
from apps.hrm.tasks import update_all_user_facedata_cache
|
||||
from apps.system.models import User
|
||||
from django.core.cache import cache
|
||||
|
||||
class HRMService:
|
||||
|
||||
@classmethod
|
||||
def face_compare_from_base64(cls, base64_data):
|
||||
filename = str(uuid.uuid4())
|
||||
filepath = settings.BASE_DIR +'/temp/' + filename +'.png'
|
||||
with open(filepath, 'wb') as f:
|
||||
f.write(base64_data)
|
||||
try:
|
||||
unknown_picture = face_recognition.load_image_file(filepath)
|
||||
unknown_face_encoding = face_recognition.face_encodings(unknown_picture, num_jitters=2)[0]
|
||||
os.remove(filepath)
|
||||
except:
|
||||
os.remove(filepath)
|
||||
return None, '识别失败,请调整位置'
|
||||
|
||||
# 匹配人脸库
|
||||
face_datas = cache.get('face_datas')
|
||||
if face_datas is None:
|
||||
update_all_user_facedata_cache()
|
||||
face_datas = cache.get('face_datas')
|
||||
face_users = cache.get('face_users')
|
||||
results = face_recognition.compare_faces(face_datas,
|
||||
unknown_face_encoding, tolerance=0.45)
|
||||
for index, value in enumerate(results):
|
||||
if value:
|
||||
# 识别成功
|
||||
user = User.objects.get(id=face_users[index])
|
||||
return user, ''
|
||||
return None, '人脸未匹配,请调整位置'
|
||||
|
||||
@classmethod
|
||||
def get_facedata_from_img(cls, img_path):
|
||||
try:
|
||||
photo_path = settings.BASE_DIR + img_path
|
||||
picture_of_me = face_recognition.load_image_file(photo_path)
|
||||
my_face_encoding = face_recognition.face_encodings(picture_of_me, num_jitters=2)[0]
|
||||
face_data_list = my_face_encoding.tolist()
|
||||
return face_data_list, ''
|
||||
except:
|
||||
return None, '人脸数据获取失败请重新上传图片'
|
|
@ -2,7 +2,6 @@ from __future__ import absolute_import, unicode_literals
|
|||
|
||||
from celery import shared_task
|
||||
from apps.hrm.models import Employee
|
||||
from django.core.cache import cache
|
||||
|
||||
|
||||
@shared_task
|
||||
|
@ -12,19 +11,4 @@ def update_all_employee_not_atwork():
|
|||
"""
|
||||
Employee.objects.all().update(is_atwork=False, last_check_time = None, not_work_remark=None)
|
||||
|
||||
@shared_task
|
||||
def update_all_user_facedata_cache():
|
||||
"""
|
||||
更新人脸数据缓存
|
||||
"""
|
||||
facedata_queyset = Employee.objects.filter(face_data__isnull=False,
|
||||
user__is_active=True).values('user', 'face_data')
|
||||
face_users = []
|
||||
face_datas = []
|
||||
for i in facedata_queyset:
|
||||
face_users.append(i['user'])
|
||||
face_datas.append(i['face_data'])
|
||||
cache.set('face_users', face_users, timeout=None)
|
||||
cache.set('face_datas', face_datas, timeout=None)
|
||||
|
||||
|
|
@ -1,12 +1,9 @@
|
|||
from django.shortcuts import render
|
||||
from django.utils import timezone
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.viewsets import ModelViewSet, GenericViewSet
|
||||
from rest_framework.mixins import UpdateModelMixin, RetrieveModelMixin, CreateModelMixin, ListModelMixin
|
||||
from apps.hrm.errors import NO_NEED_LEVEL_REMARK
|
||||
from apps.hrm.filters import ClockRecordFilterSet, EmployeeFilterSet, NotWorkRemarkFilterSet
|
||||
from apps.hrm.services import HRMService
|
||||
from apps.hrm.tasks import update_all_user_facedata_cache
|
||||
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
|
||||
from apps.hrm.models import ClockRecord, Employee, NotWorkRemark
|
||||
from apps.hrm.serializers import ClockRecordListSerializer, EmployeeNotWorkRemarkSerializer, EmployeeSerializer, FaceClockCreateSerializer, FaceLoginSerializer, NotWorkRemarkListSerializer
|
||||
|
||||
|
@ -20,18 +17,20 @@ from apps.system.models import User
|
|||
from apps.system.serializers import UserSimpleSerializer
|
||||
from rest_framework.permissions import AllowAny
|
||||
from rest_framework.decorators import action
|
||||
from apps.utils.viewsets import CustomModelViewSet, CustomGenericViewSet
|
||||
from rest_framework.exceptions import ParseError
|
||||
|
||||
|
||||
# Create your views here.
|
||||
class EmployeeViewSet(CreateUpdateModelAMixin, OptimizationMixin, UpdateModelMixin, ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
||||
class EmployeeViewSet(CustomModelViewSet):
|
||||
"""
|
||||
员工详细信息
|
||||
员工信息管理
|
||||
"""
|
||||
perms_map = {'get': '*', 'put': 'employee_update'}
|
||||
queryset = Employee.objects.all()
|
||||
select_related_fields = ['user']
|
||||
filterset_class = EmployeeFilterSet
|
||||
serializer_class = EmployeeSerializer
|
||||
search_fields = ['user__name', 'number', 'user__username']
|
||||
search_fields = ['name', 'number', 'user__username']
|
||||
ordering = ['-pk']
|
||||
|
||||
def update(self, request, *args, **kwargs):
|
||||
|
@ -81,107 +80,30 @@ class EmployeeViewSet(CreateUpdateModelAMixin, OptimizationMixin, UpdateModelMix
|
|||
instance.update_by = request.user
|
||||
instance.save()
|
||||
return Response()
|
||||
return Response('无需填写离岗说明', status=status.HTTP_400_BAD_REQUEST)
|
||||
raise ParseError(**NO_NEED_LEVEL_REMARK)
|
||||
|
||||
|
||||
class ClockRecordViewSet(CreateModelMixin, ListModelMixin, GenericViewSet):
|
||||
class ClockRecordViewSet(ListModelMixin, CustomGenericViewSet):
|
||||
"""
|
||||
打卡记录
|
||||
"""
|
||||
perms_map = {'get':'*', 'post':'*'}
|
||||
authentication_classes = []
|
||||
permission_classes = [AllowAny]
|
||||
queryset = ClockRecord.objects.select_related('create_by').all()
|
||||
queryset = ClockRecord.objects.all()
|
||||
select_related_fields = ['create_by']
|
||||
serializer_class = ClockRecordListSerializer
|
||||
filterset_class = ClockRecordFilterSet
|
||||
ordering = ['-pk']
|
||||
|
||||
def get_serializer_class(self):
|
||||
if self.action == 'create':
|
||||
return FaceClockCreateSerializer
|
||||
return super().get_serializer_class()
|
||||
|
||||
def create(self, request, *args, **kwargs):
|
||||
now = timezone.now()
|
||||
now_local = timezone.localtime()
|
||||
if 8<=now_local.hour<=17:
|
||||
base64_data = base64.urlsafe_b64decode(tran64(
|
||||
request.data.get('base64').replace(' ', '+')))
|
||||
user, msg = HRMService.face_compare_from_base64(base64_data)
|
||||
if user:
|
||||
ins, created = ClockRecord.objects.get_or_create(
|
||||
create_by = user, create_time__hour__range = [8,18],
|
||||
create_time__year=now_local.year, create_time__month=now_local.month,
|
||||
create_time__day=now_local.day,
|
||||
defaults={
|
||||
'type':ClockRecord.ClOCK_WORK1,
|
||||
'create_by':user,
|
||||
'create_time':now
|
||||
})
|
||||
if not created:
|
||||
ins.update_time = now
|
||||
ins.save()
|
||||
# 设为在岗
|
||||
Employee.objects.filter(user=user).update(is_atwork=True, last_check_time=now)
|
||||
return Response(UserSimpleSerializer(instance=user).data)
|
||||
return Response(msg, status=status.HTTP_400_BAD_REQUEST)
|
||||
return Response('非打卡时间范围', status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
|
||||
class NotWorkRemarkViewSet(ListModelMixin, GenericViewSet):
|
||||
class NotWorkRemarkViewSet(ListModelMixin, CustomGenericViewSet):
|
||||
"""
|
||||
离岗说明
|
||||
"""
|
||||
perms_map = {'get':'*'}
|
||||
queryset = NotWorkRemark.objects.select_related('user').all()
|
||||
queryset = NotWorkRemark.objects.all()
|
||||
select_related_fields = ['user']
|
||||
serializer_class = NotWorkRemarkListSerializer
|
||||
filterset_class = NotWorkRemarkFilterSet
|
||||
ordering = ['-pk']
|
||||
|
||||
|
||||
import base64
|
||||
|
||||
def tran64(s):
|
||||
missing_padding = len(s) % 4
|
||||
if missing_padding != 0:
|
||||
s = s+'='* (4 - missing_padding)
|
||||
return s
|
||||
|
||||
class FaceLogin(CreateAPIView):
|
||||
authentication_classes = []
|
||||
permission_classes = []
|
||||
serializer_class = FaceLoginSerializer
|
||||
|
||||
|
||||
def create(self, request, *args, **kwargs):
|
||||
"""
|
||||
人脸识别登录
|
||||
"""
|
||||
base64_data = base64.urlsafe_b64decode(tran64(request.data.get('base64').replace(' ', '+')))
|
||||
user, msg = HRMService.face_compare_from_base64(base64_data)
|
||||
if user:
|
||||
refresh = RefreshToken.for_user(user)
|
||||
# 可设为在岗
|
||||
now = timezone.now()
|
||||
now_local = timezone.localtime()
|
||||
if 8<=now_local.hour<=17:
|
||||
ins, created = ClockRecord.objects.get_or_create(
|
||||
create_by = user, create_time__hour__range = [8,18],
|
||||
create_time__year=now_local.year, create_time__month=now_local.month,
|
||||
create_time__day=now_local.day,
|
||||
defaults={
|
||||
'type':ClockRecord.ClOCK_WORK1,
|
||||
'create_by':user,
|
||||
'create_time':now
|
||||
})
|
||||
# 设为在岗
|
||||
if created:
|
||||
Employee.objects.filter(user=user).update(is_atwork=True, last_check_time=now)
|
||||
|
||||
return Response({
|
||||
'refresh': str(refresh),
|
||||
'access': str(refresh.access_token),
|
||||
'username':user.username,
|
||||
'name':user.name
|
||||
})
|
||||
return Response(msg, status=status.HTTP_400_BAD_REQUEST)
|
|
@ -12,6 +12,7 @@ from rest_framework.exceptions import ParseError, APIException
|
|||
from django.db import transaction
|
||||
from apps.third.tapis import dhapis
|
||||
from rest_framework.validators import UniqueValidator
|
||||
from django.contrib.auth.hashers import make_password
|
||||
|
||||
class IntervalSerializer(CustomModelSerializer):
|
||||
class Meta:
|
||||
|
@ -275,6 +276,7 @@ class UserCreateSerializer(CustomModelSerializer):
|
|||
fields = ['username', 'name', 'avatar', 'is_active']
|
||||
|
||||
|
||||
|
||||
class PasswordChangeSerializer(serializers.Serializer):
|
||||
old_password = serializers.CharField(label="原密码")
|
||||
new_password1 = serializers.CharField(label="新密码1")
|
||||
|
|
|
@ -305,14 +305,10 @@ class UserViewSet(CustomModelViewSet):
|
|||
|
||||
创建用户
|
||||
"""
|
||||
password = request.data.get('password', None)
|
||||
if password:
|
||||
password = make_password(password)
|
||||
else:
|
||||
password = make_password('0000')
|
||||
password = make_password('0000')
|
||||
serializer = self.get_serializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
serializer.save(password=password)
|
||||
serializer.save(password=password, belong_dept=None)
|
||||
return Response(data=serializer.data)
|
||||
|
||||
@action(methods=['put'], detail=False,
|
||||
|
|
|
@ -19,7 +19,9 @@ class CustomModelSerializer(DynamicFieldsMixin, serializers.ModelSerializer):
|
|||
if self.request:
|
||||
if getattr(self.request, 'user', None):
|
||||
validated_data['create_by'] = self.request.user
|
||||
if getattr(self.request.user, 'belong_dept', None):
|
||||
if 'belong_dept' in validated_data: # 如果指定数据归属部门
|
||||
pass
|
||||
elif getattr(self.request.user, 'belong_dept', None):
|
||||
validated_data['belong_dept'] = self.request.user.belong_dept
|
||||
return super().create(validated_data)
|
||||
|
||||
|
|
Loading…
Reference in New Issue